在c中使用fgets()函数

问题描述 投票:0回答:1

我是 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
给出输出: ` 完成

完成 帕布纳完成

完成 故事完成 ` 不知道发生了什么。我只想仅将五个字符作为输入。如果用户输入是四个字符,则换行符将被接收并存储为一个字符,而如果它是五个字母,则应保持原样。那么,我缺少什么?

c string
1个回答
0
投票

您的代码中有太多额外的工作。请问,为什么要先将输入读取到

temporary
中,然后将其复制到另一个字符串中,而不是直接将输入读取到最终字符串中?

现在关于错误:

  1. fgets(temporary,6,stdin);
    

    有问题。

    temporary
    只能容纳5个字符,不能容纳6个。这只是 引发缓冲区溢出攻击。
    6
    应更改为
    sizeof temporary

  2. if(strlen(temporary)>5)
    

    不可能是真的。

    fgets()
    将替换最后一个字符(第 6 个字符) 字符)将是空字节(''),以及
    strlen()
    的返回值 总是小于或等于 5,永远不会大于 5。

  3. 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]);
}
© www.soinside.com 2019 - 2024. All rights reserved.