这部分在描述中gets
可能会令人困惑:
它需要所有字符直到(但不包括)换行符
或许更好的说法是takes所有角色包括换行符但是stores所有字符不包括换行符。
所以如果用户输入some string
, the gets
函数将读取some string
和来自用户终端的换行符,但仅存储some string
在缓冲区中 - 换行符丢失。这很好,因为无论如何没有人想要换行符 - 它是一个控制字符,而不是用户想要输入的数据的一部分。
Therefore, if you only press enter, gets
interprets it as an empty string. Now, as noted by some people, your code has multiple bugs.
printf("This is the input as a string: %s\n", input);
这里没问题,尽管您可能想用一些人工字符分隔字符串以更好地进行调试:
printf("This is the input as a string: '%s'\n", input);
printf("Is it the string end character? %d\n", input == '\0');
不好:您想在这里检查 1 个字节,而不是整个缓冲区。如果你尝试将整个缓冲区与 0 进行比较,答案总是false
因为编译器会转换\0
to NULL
并将比较解释为“缓冲区是否存在?”。
正确的方法是:
printf("Does the first byte contain the string end character? %d\n", input[0] == '\0');
这仅比较 1 个字节\0
.
printf("Is it a newline string? %d\n", input == "\n");
不好:这将缓冲区的地址与"\n"
- 答案总是false
。 C 中比较字符串的正确方法是strcmp
:
printf("Is it a newline string? %d\n", strcmp(input, "\n") == 0);
注意特殊用法:strcmp
当字符串相等时返回 0。
printf("Is it the empty string? %d\n", input == "");
这里同样的错误。使用strcmp
这里也:
printf("Is it the empty string? %d\n", strcmp(input, "") == 0);
顺便说一句,正如人们常说的,gets
不能以安全的方式使用,因为它不支持缓冲区溢出保护。所以你应该使用fgets http://en.cppreference.com/w/c/io/fgets相反,尽管它不太方便:
char input[100];
while (fgets(input, sizeof input, stdin))
{
...
}
这可能会导致混乱:fgets
不会从它读取的输入中删除换行字节。所以如果你更换gets
在你的代码中fgets
,你会得到不同的结果。幸运的是,您的代码将清楚地说明其中的差异。