您的数组有一个典型的too-short-by-one字节问题.继续我的 comments .在C中,字符串被定义为以'\0'
(nul-character)结尾的字符序列.这就是所有接受字符串作为参数的函数知道字符串在哪里结束的方法.
为了防止出现问题,在使用"%s"
或"%[..]"
转换说明符填充数组时,必须始终指定field-width修饰符.必须手动提供field-width修饰符,因为它不能用命名常量指定,也不能作为参数提供给scanf()
.将字段宽度修饰符设置为size-of-array - 1
,以将scanf()
将读取的字符数量限制为比数组大小小1--确保NUL终止字符保留1字节.
对于您的数组,这将是"%3s"
--这显示了您有off-by-one个错误.发生的情况是在数组末尾之外写入,覆盖下一个数组的第一个字符的地址,依此类推.
要正确使用scanf()
,必须始终判断回车,如果填充数组,则始终使用field-width修饰符.
从您的代码中组合一个简短的示例,并展示几种输出方法,您可以这样做:
#include <stdio.h>
#define MAXC 64 /* if you need a constant, define one (or more) */
int main() {
/* use a constant to set array size (not Magic-Numbers) */
char word0[MAXC], word1[MAXC], word2[MAXC];
/* prompt for input */
puts ("enter 3 space separated words");
/* ALWAYS use the field-width modifier filling arrays and
* ALWAYS check the scanf return.
*/
if (scanf("%63s%63s%63s", word0, word1, word2) != 3) {
fputs ("error: reading words.\n", stderr);
return 1;
}
putchar ('\n'); /* tidy up with newline */
fputs ("word0: ", stdout);
for (int i = 0; word0[i]; i++) { /* if you want to loop chars */
putchar (word0[i]);
}
putchar ('\n'); /* tidy up with newline */
fputs ("word1: ", stdout);
puts (word1); /* otherwise just output the word */
fputs ("word2: ", stdout);
puts (word2);
}
(Note: puts()
将始终将'\n'
附加到正在输出的字符串.如果您需要行结束控制,那么使用fputs()
,但不需要.关键是,当您的输出字符串中没有转换时,您不需要调用变量printf()
函数.)
Example Use/Output个
使用您的示例:
$./bin/3words
enter 3 space separated words
xzcv abcd 1234
word0: xzcv
word1: abcd
word2: 1234
或者三个不同大小的单词:
$ ./bin/3words
enter 3 space separated words
My Elephant Sings
word0: My
word1: Elephant
word2: Sings
如果您有进一步的问题,请告诉我--并考虑用fgets()
来阅读所有输入,一次读一行,避免scanf()
个trap ……