我正在尝试创建一个简单的程序,使用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;
}
答案 0 :(得分:1)
您正在为每个w
元素重复使用w_arr
(即它们都指向同一个位置)。您需要为每个字符串分配一个
变化:
w_arr[c] = w;
要:
w_arr[c] = strdup(w);
答案 1 :(得分:1)
声明
w_arr[c] = w;
确保w_arr
的所有元素都指向同一个指针w
。 w
循环结束后保存在while
的数据是读取的最后一个输入。因此,您会看到w_arr
的所有元素的相同输出。
我可以想到几种解决这个问题的方法。
分配到strdup
w_arr[c]
w_arr[c] = strdup(w);
如果您的平台上没有strdup
,则很容易实现。{/ p>
char* strdup(char const* in)
{
char* ret = malloc(strlen(in)+1);
strcpy(ret, in);
return ret;
}
在w
循环中为while
分配第二,第三等输入的内存。
而不是
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));
}
确保在函数结束前添加对deallocate mmory的调用。
free(w);
for (int i = 0; i < 3; ++i )
free(w_arr[i]);
答案 2 :(得分:1)
您正在将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
,然后将新字符数组分配给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;
}
答案 3 :(得分: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
中获得超过必需的字符数。
答案 4 :(得分:0)
您最好使用strdup
并添加string.h
。
w_arr[c] = w;
要:
w_arr[c] = strdup(w);
并且strcpy
不安全,您最好使用strncpy
;