![](/img/trans.png)
[英]C Programming: fgets() function is not reading the values that I think it should
[英]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.