我是 C 新手。请考虑我的以下代码:
#include <stdio.h>
#include <string.h>
int main()
{
char strs[5][6];
char temporary[5]="";
for(int i=0;i<5;i++)
{
fgets(temporary,6,stdin);
if(strlen(temporary)>5)
temporary[strlen(temporary)-1]='\0';
strcpy(strs[i],temporary);
}
printf("%s done\n",strs[0]);
printf("%s done\n",strs[1]);
printf("%s done\n",strs[2]);
printf("%s done\n",strs[3]);
printf("%s done\n",strs[4]);
return 0;
}
该问题可能有重复项,但我找不到。现在,我遇到了一些困惑。首先,
temporary[strlen(temporary)-1]='\0';
行删除了字符串中的最后一个字符。因此,如果用户输入 \n
,那么 fgets()
就会遇到换行符 [为了清楚起见,请考虑在这些输入中,字符长度从来都不是 5,它始终是 4]。然后,这是我收到的输出:
如果输入是:Barn
我永远无法按 Enter 键转到下一行。此外,所有输入都是五个字母的输出更加可怕。
Dhaka Pabna Tales
给出输出:
`
完成
完成 帕布纳完成
完成 故事完成 ` 不知道发生了什么。我只想仅将五个字符作为输入。如果用户输入是四个字符,则换行符将被接收并存储为一个字符,而如果它是五个字母,则应保持原样。那么,我缺少什么?
您的代码中有太多额外的工作。请问,为什么要先将输入读取到
temporary
中,然后将其复制到另一个字符串中,而不是直接将输入读取到最终字符串中?
现在关于错误:
fgets(temporary,6,stdin);
有问题。
temporary
只能容纳5个字符,不能容纳6个。这只是
引发缓冲区溢出攻击。 6
应更改为
sizeof temporary
。
if(strlen(temporary)>5)
不可能是真的。
fgets()
将替换最后一个字符(第 6 个字符)
字符)将是空字节(''),以及strlen()
的返回值
总是小于或等于 5,永远不会大于 5。
temporary[strlen(temporary)-1]='\0';
又在做额外的工作了。为什么不缓存
strlen()
的值而不是
再次调用它吗? (正如 Barmar 在评论中提到的,编译器可能会对此进行优化)。但这样的计算就有问题了。当空的时候会发生什么
字符串作为输入提供? strlen(temporary)
将返回 0,而你
将写入越界内存,从而调用 undefined
行为。这样更好:
size_t len = strlen();
if (len > 0 && temporary[len - 1] == '\n') {
temporary[len-1] = 0;
}
除此之外,这 5 个
printf()
调用:
printf("%s done\n",strs[0]);
printf("%s done\n",strs[1]);
printf("%s done\n",strs[2]);
printf("%s done\n",strs[3]);
printf("%s done\n",strs[4]);
可以替换为循环和单个
printf()
调用:
for (size_t i = 0; i < 5; ++i) {
printf("%s done\n", strs[i]);
}