繁体   English   中英

关于fgets()函数字符限制的C编程?

[英]C programming on fgets() function characters limitation?

样例代码:

    int i;
    char word [10][15];
    for (i = 0; i < 10; i++){

      fgets(word[i], 16, stdin);

    }

因此,我最多接受10个字符串用户输入,每个字符串的长度不能超过15个字符长(因此16个字符是因为\\n存储在fgets()方法的最后一个字符处,对吗?) 。

我的问题是当我想打印出words数组中的单词时。 有时候是这样的:

输入:

abcdefghijklmnopqrstuvwxyz

输出:

abcdefghijklmnopqrstuvwxyz

pqrstuvwxyz

我不知道为什么会这样。 似乎fgets()在接受输入的15个字符后不会停止。

编辑:

    int j;
    for (j = 0; j < 10; j++){
      printf("%s", word[j]);
    }

请记住,在C编程语言中,每个字符串都以\\0结尾。 fgets函数读取的字符最多比您允许其写入缓冲区的字符少,因此它可以使用\\0字节终止缓冲区中的字符串。 现在,在您的代码允许fgets写一个字节更进word不是每个char[15]word了。 最初, word数组看起来像这样:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ...
^                             ^                             ^
word[0]                       word[1]                       word[2]

? 代表未定义的值。 在代码首次调用fgets之后, words如下所示:

a b c d e f g h i j k l m n o \0? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ...
^                             ^                             ^
word[0]                       word[1]                       word[2]

观察到fgets写的字节多于words[0]空间,因此它写入了属于word[1] 但是,如果要使用printf打印出word[0]的内容,则字符串abcdefghijklmno将作为printf打印输出,直到遇到\\0字节为止。 现在,在第二次调用fgets之后,看看word是什么样子:

a b c d e f g h i j k l m n o p q r s t u v w x y z \n\0? ? ? ? ? ? ...
^                             ^                             ^
word[0]                       word[1]                       word[2]

在此调用中, fgets不会超出word[1]的末尾写入,因为它之前遇到了换行符( \\n )字节。 观察到word[0]字符串的尾随\\0字节已被覆盖,因为该字符串进入了word[1]占用的存储区。

现在,如果您打印该怎么办? printf的第一次调用从a开始开始打印,直到遇到\\0字符为止。 这导致字符串abcdefghijklmnopqrstuvwxyz\\n被打印,因为在o后面没有\\0字节。 printf的第二次调用从word[1]起始位置开始,在p直到看到\\0为止,从而导致pqrstuvwxyz\\n被打印。

现在如何解决这个问题? 要么使数组中的每个字符串更长,要么让fgets只读取15 16字符而不是16字符。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM