簡體   English   中英

使用scanf將字符串讀入字符串數組

[英]Using scanf to read strings into an array of strings

我正在嘗試制作一個簡單的程序,該程序始終使用scanf從標准輸入中讀取字符串,並將其放入字符串數組中(現在,我僅使用3個單詞對其進行測試,因此最后僅使用3個打印語句)。 我可以繼續讀取直到沒有更多的字符串為止,但是遇到一個錯誤,在該錯誤中,循環完成后,數組中的所有字符串都是最后一個讀入的字符串。我嘗試將print語句放入其中要調試的循環,它正在讀取正確的字符串。 但是,當循環結束時,數組中的所有字符串都是讀入的最后一個字符串。有人能指出我在哪里出錯嗎? 謝謝。

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



int main(void) {
    int c = 0;
    char** w_arr = malloc(3*sizeof(char*));
    char* w = malloc(10*sizeof(char));

    while (scanf("%s", w) == 1) {
        w_arr[c] = w;
        //printf("%s", w_arr[c]); debug print statement
        c++;
    }

    printf("%s, %s, %s\n", w_arr[0], w_arr[1], w_arr[2]);
    return 0;
}

您正在為每個w_arr元素重用w (即它們都指向同一位置)。 您需要為每個字符串分配一個

更改:

w_arr[c] = w;

至:

w_arr[c] = strdup(w);

該聲明

    w_arr[c] = w;

確保w_arr所有元素w_arr指向相同的指針w while循環結束后在w保留的數據是最后讀取的輸入。 因此,您將從w_arr所有元素中看到相同的輸出。

我可以想到幾種解決此問題的方法。

  1. 分配給w_arr[c]時使用strdup

     w_arr[c] = strdup(w); 

    如果您的平台上沒有strdup ,則很容易實現。

     char* strdup(char const* in) { char* ret = malloc(strlen(in)+1); strcpy(ret, in); return ret; } 
  2. while循環中為第二,第三等輸入分配w內存。

    代替

     char* w = malloc(10*sizeof(char)); while (scanf("%s", w) == 1) { w_arr[c] = w; //printf("%s", w_arr[c]); debug print statement c++; } 

    采用

     char* w = malloc(10*sizeof(char)); while (scanf("%s", w) == 1) { w_arr[c] = w; //printf("%s", w_arr[c]); debug print statement c++; w = malloc(10*sizeof(char)); } 

確保在函數結束之前添加調用以釋放mmory。

    free(w);
    for (int i = 0; i < 3; ++i )
       free(w_arr[i]);

您正在將w_arr的每個元素設置為僅分配一次的單個緩沖區w 您可以通過在循環后添加以下行來打印出w_arr的內容來查看此內容:

printf("Addresses of strings: %p, %p, %p\n", w_arr[0], w_arr[1], w_arr[2]);

您應該看到類似於以下內容的輸出:

[hwibell@localhost tmp]$ ./strings
123
456
789
Addresses of strings: 0x1b0b030, 0x1b0b030, 0x1b0b030 <-- Same address!
Contents of strings: 789, 789, 789

如您所見, w_arr每個元素w_arr指向內存中的相同地址。 要解決此問題,您將需要每次分配w ,然后將新的字符數組分配給w_arr。

#define NUM_OF_STRINGS 3
#define MAX_CHARS      10

int main(void) {
    char** w_arr = malloc(NUM_OF_STRINGS * sizeof(char*));

    for (int i = 0; i < NUM_OF_STRINGS; ++i) {
        w_arr[i] = malloc(MAX_CHARS * sizeof(char)); // allocate a new buffer for each element in w_arr
        scanf("%s", w_arr[i]);
    }

    printf("%s, %s, %s\n", w_arr[0], w_arr[1], w_arr[2]);
    return 0;
}
 w_arr[c] = w;

w_arr[c]指向w它在循環結束時的內容是最后讀取的字符串,因此您將得到最后一個打印的字符串。

您為w_arr每個指針分配內存-

 char** w_arr = malloc(3*sizeof(char*));      //allocated memory for 3 char *

 while (scanf("%s", w) == 1 && c<3) {
      w_arr[c]=malloc(10*sizeof(**w_arr));    // allocate memory to each char *
      strcpy(w_arr,w);                        //copy string
    //printf("%s", w_arr[c]); debug print statement
      c++;
 }

然后閱讀后使用strcpy

注意 -將scanf更改為while (scanf("%9s", w) == 1) {以避免在w獲得超出要求的字符數。

您最好使用strdup並包含string.h

w_arr[c] = w;

至:

w_arr[c] = strdup(w);

而且strcpy是不安全的,您最好改用strncpy

暫無
暫無

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

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