簡體   English   中英

為什么打印出 char 數組會產生隨機字符?

[英]Why does printing out an array of char result in random characters?

我正在嘗試學習編程並正在做一些隨機的問題和任務。 任務是寫出字符串的最后三個字符,這就是我想出的。 請不要為我解決這個問題,我問的是我的輸出/結果,而不是讓任何人為我解決問題:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int func(char *input_1, char *input_2) {
    char last_three_digits_1[3]; // define two arrays that hold the last three characters
    char last_three_digits_2[3];

    int x = 0;
    for(int y = strlen(input_1) - 4; y < strlen(input_1) - 1; y++) {
        last_three_digits_1[x] = input_1[i];
        x++;
    }

    x = 0; // repeat for the second string
    for(int z = strlen(input_2) - 4; z < strlen(input_2) - 1; z++) {
        last_three_digits_2[x] = input_2[i];
        x++;
    }


    printf("last3_1: %s, \nlast3_2: %s\n", last_three1, last_three2); // this seem to access random memory because it outputs "abc" followed by random "-???" or "-????" or "-?2?2". Same for the second array.

    return 0;
}

int main(int argc, char * argv[] ) {
    if(argc == 3) { // needs to be two strings. E.g: "abcd efghi"
        if(strlen(argv[1]) >= 3 || strlen(argv[2]) >= 3) { // if any of the strings are less than 3 in length, e.g. "ab wadnkwa" then do not proceed.
            func(argv[1], argv[2]); // send the user input to the function
        }

        return 0; // maybe redundant
    }

    return 0; // return 0 for failure
}

if語句中的條件

if(strlen(argv[1]) >= 3 || strlen(argv[2]) >= 3)

意味着其中一個字符串的長度可以小於 3。在這種情況下,function func可以調用未定義的行為。

看來你的意思

if(strlen(argv[1]) >= 3 && strlen(argv[2]) >= 3)

否則,您需要在 function func中檢查字符串的長度是否大於或等於 3,然后再輸出最后三個字符。

如果一個字符串恰好有三個字符,那么例如在這個循環中

for(int i = strlen(text1) - 4; i < strlen(text1) - 1; i++)

變量i可以有一個實現定義的值,例如 -1,因此這個表達式text1[i]調用未定義的行為。

function 的返回類型int沒有意義。

請注意,如果您使用格式%s到 output 一個使用printf的字符數組,那么該數組應包含一個字符串,該字符串是一個以零字符'\0'結尾的字符序列。

因此 main 中的 if 語句和 function 本身都沒有意義。

對於 output 字符串的最后三個(或任何其他數字)字符,無需創建輔助數組。 它可以做得更簡單。

例如

void func( const char *text1, const char *text2, size_t n )
{
    size_t n1 = strlen( text1 );
   
    if ( !( n1 < n ) ) text1 += n1 - n;

    size_t n2 = strlen( text2 );

    if ( !( n2 < n ) ) text2 += n2 - n;

    printf( "last%zu_1: %s, \nlast%zu_2: %s\n", n, text1, n, text2 );
}

function 可以這樣調用

func( argv[1], argv[2], 3 );

使用 function 這樣的聲明,您可以 output 兩個字符串的任意數量的最后一個字符。 還要考慮到 function 參數具有限定符const ,因為傳遞的字符串在 function 中沒有更改。

這是一個演示程序

#include <stdio.h>
#include <string.h>

void func( const char *text1, const char *text2, size_t n )
{
    size_t n1 = strlen( text1 );

    if (!( n1 < n )) text1 += n1 - n;

    size_t n2 = strlen( text2 );

    if (!( n2 < n )) text2 += n2 - n;

    printf( "last%zu_1: %s, \nlast%zu_2: %s\n", n, text1, n, text2 );
}

int main( void )
{
    func( "Hello", "World", 3 );
}

程序 output 是

last3_1: llo,
last3_2: rld
char last_three1[3]; // define two arrays that hold the last three characters
char last_three2[3];

您需要空間來容納\0字符,因為%s期望char*\0終止。

char last_three1[4]; 
char last_three2[4];

….
last_three1[x] = '\0';
x = 0; // repeat for the second string
for(int i = strlen(text2) - 4; i < strlen(text2) - 1; i++) {
    last_three2[x] = text2[i];
    x++;
}
last_three2[x] = '\0';

C 中的字符串以單個零字節結尾。

你不是以零結束字符串,所以printf不知道在哪里停止打印(你很幸運你的程序沒有徹底崩潰)。

我會重構這樣的東西,所以你有一個 function,它只復制最后三個字節並以零終止字符串:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// out must be an array that can hold 4 bytes
// in must be >= 3 characters; otherwise this function returns non-zero
int get_last_three(char *out, const char *in) {
  int len = strlen(in);
  if (len < 3)
    return -1;
  for (int i = len - 3; i < len; i++) {
    *out = in[i];
    out++;
  }
  *out = 0; // Zero-terminate
  return 0;
}

int main(int argc, char *argv[]) {
  char out[4];
  for (int i = 1; i < argc; i++) {
    if (get_last_three(out, argv[i]) == 0) {
      printf("last3_%d: %s\n", i, out);
    }
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM