当我的fgets输入超过指定的缓冲区大小时,我的程序(非常简单)似乎表现出奇怪的行为

时间:2019-01-15 23:08:52

标签: c fgets

我刚开始使用C语言,我编写了一个非常简单的程序,其中包含员工ID,工作时间和薪水,并输出工资和给定的ID。

我正在用fgets捕获ID,但是,当我输入一个字符串长于指定的缓冲区大小(此处为10)时,我的程序似乎“崩溃”。它在同一行上打印下两个printf,跳过第一行的输入,这显然会破坏程序。

当用fgets捕获的ID为<=缓冲区大小时,它可以正常工作。关于这个问题有点困惑。 FWIW我在GNU GCC编译器中使用代码块。

谢谢。

word='yahoo'
var='${ -b :board}'
word+=${var:0:3}

2 个答案:

答案 0 :(得分:2)

原因是,如果行的其余部分大于传递的缓冲区,则不会被fgets()提取,因此保留在stdin文件流的输入缓冲区中;随后scanf()的转换失败。

您将必须检测到这种情况(例如,通过检查是否刚读的字符串中的最后一个字符不是换行符)并将输入缓冲区清空到下一个换行符,例如通过调用{{1} }循环到换行符(或EOF)。然后致电getchar()

示例代码(未经测试和EOF检查仍不存在):

scanf()

请记住检查您的fgets(ID, sizeof(ID), stdin); if (ID[strlen(ID)-1] != '\n') { while (getchar() != '\n') ; } 调用的返回值,以查看转换是否成功!

答案 1 :(得分:1)

您观察到的行为是因为,如果因为没有空间而没有将换行符写入ID,则它将保留在输入缓冲区中,由于格式说明符字符串not,后续的两个scanf()调用不会被占用读取空白。

输入新行时

fgets()返回,并将新行写入缓冲区。在这种情况下,您需要一个12个字符的缓冲区-容纳换行符和nul终止符。将缓冲区初始化为零也是一个好主意。

char ID[11] = {0} ;

fgets()之后,您可能需要用nul替换换行符。

要将换行符替换为nul或丢弃保留换行符的输入缓冲区数据:

char* end = strrchr( ID, `\n` ) ;
if( end != NULL) 
{ 
    *end = `\0` 
}
else
{
    char c ;
    do
    {
        c = getchar() ;
    } while( c != '\n' && c != EOF ) ;
}