[英]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
所有元素中看到相同的输出。
我可以想到几种解决此问题的方法。
分配给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; }
在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.