#include #include int main() { int in,i,j; char *arr[100],str[14]; scanf("%d",&in); i=0; while(i<in) { scanf("%s",str); arr[i]=str; // printf("%sn",arr[i]); i++; } i=0; while(i<in) { printf("%sn",arr[i++]); } return 0; }
/ *在这段代码中,我从用户那里获取输入字符串,并希望将其打印回来,但它正在打印用户输入的最后一个字符串.WHY ?? * /
您将每个字符串存储在同一位置,每次都覆盖前一个字符串。 不要那样做。 str
是一个缓冲区,数组arr
中的所有指针都指向它。
你的问题是arr[i]=str;
声明。
str
是一个静态分配的数组, 所有 arr[i]
都存储它的基地址。
由于str
的值在每次调用scanf()
被覆盖,在你的情况下,只有访问任何 arr[i]
才会打印存储在str
的最后一个值。
你需要做什么
注意:最后不要忘记free()
分配的内存。
因为您将内存地址分配给指针数组。 所以数组的地址不会改变。 每个指针数组都指向同一个地址。
当新值获得时,它将该值放在数组中相同的地址位置。
所以所有的值都保持不变。 所以避免这种情况你可以使str成为指针。 并动态地将内存分配给该指针。
char *str;
在while循环中进行分配str=malloc(MAX);
while(i
100是一个例子。 你可以使用你需要的价值。
在循环中尝试这样的事情。
while(i
因为你继续对所有字符串使用相同的char[] str
。
相反,您可能希望为每个字符串分配一个新的内存块。 使用后不要忘记再次释放它们。
你可以在循环中检查它
while(i
而且你看到不仅字符串是相同的,而且它的地址也是如此。
您需要为每个字符串arr[i]
分配内存,然后使用strcpy
作为复制字符串。
在循环中添加如下所示的代码。
arr[i]=malloc(strlen(str)+1); strcpy(arr[i],str);
也永远不会忘记在程序结束时为上面的分配释放内存。
除了其他响应之外,还有一些替代方法可以用来读取字符串输入,您可以使用它们来简化程序中需要跟踪的内容。 正如其他人所建议的那样,不要将arr
声明为char *arr[100]
,而是将其声明为pointer-to-pointer-to-char
。
char **arr = NULL;
这允许您分配一个字符指针数组。 您可以选择使用malloc
进行分配,也可以选择仅使用calloc
将所有指针分配并初始化zero/NULL
。
arr = calloc (100, sizeof *arr);
通过使用calloc
,这允许稍后只迭代那些包含字符串的指针。 这进一步消除了必须要求输入的字符串数量(或跟踪输入的字符串数量)。
分配指针后,需要分配空间来容纳每个字符串。 虽然对malloc
(或calloc
)的另一个调用以及对strcpy
(或strncpy
)的调用没有任何问题,但您可以使用string.h
提供的函数strdup
同时执行这两个strdup
。 strdup
唯一需要注意的是它为你分配内存。 因此,您有责任在不再需要时释放该内存。
将各个部分放在一起,以及有关scanf
字符串的注释中的信息,您可以按如下方式实现字符串集合。 注意您只需输入任意数量的字符串(最多分配100个指针),然后在完成后按空白行上的[enter]
:
#include #include #include int main () { int i = 0; /* always initialize your variables */ char **arr = NULL; char str[14] = { 0 }; arr = calloc (100, sizeof *arr); /* create 100 pointers to char* */ printf ("nEnter strings ( [enter] alone when done )nn"); while (printf (" input: ") && scanf ("%[^n]%*c", str) >= 1) arr[i++] = strdup (str); /* strdup allocates and copies */ printf ("nThe strings entered were:nn"); i = 0; /* print the array */ while (arr[i]) { printf (" arr[%2d]: %sn", i, arr[i]); i++; } i = 0; /* free memory allocated */ while (arr[i]) free (arr[i++]); if (arr) free (arr); return 0; }
输出:
$ ./bin/str_array Enter strings ( [enter] alone when done ) input: string 1 input: string 2 input: string 3 input: The strings entered were: arr[ 0]: string 1 arr[ 1]: string 2 arr[ 2]: string 3
有很多方法可以解决这个问题。 比较所有答案并为您的collections添加不同的方法。 总有一个地方会有一个人会比另一个人受益,反之亦然。 请注意,在上面的代码中,您应该检查是否有任何使用calloc
, malloc
或strdup
分配成功,并在失败时处理错误。 您还应该检查何时进入第99个sting并根据需要重新分配指针数。 为清楚起见,省略了这些检查。
valgrind内存使用总结
养成使用valgrind
始终validation内存使用情况的习惯。 它会指出你已经分配了你未能释放的内存的任何地方。 虽然像这样的一小段代码中的内存将在exit
释放,但是在更长的代码中,无法跟踪分配的内存会导致程序在不再需要内存后使用大量内存(内存)泄漏)。 使用valgrind
快速检查会发现任何问题或确认一切顺利:
==28677== HEAP SUMMARY: ==28677== in use at exit: 0 bytes in 0 blocks ==28677== total heap usage: 4 allocs, 4 frees, 827 bytes allocated ==28677== ==28677== All heap blocks were freed -- no leaks are possible ==28677== ==28677== For counts of detected and suppressed errors, rerun with: -v ==28677== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
如果您有任何疑问,请告诉我。
以上就是c/c++开发分享为什么输出是用户的最后一个字符串?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/519705.html