gpt4 book ai didi

c - gets() 只读取一个换行符时保存了什么

转载 作者:太空宇宙 更新时间:2023-11-04 06:22:16 25 4
gpt4 key购买 nike

这是 Prata 的 C Primer Plus 中对 gets() 的描述:

It gets a string from your system's standard input device, normally your keyboard. Because a string has no predetermined length, gets() needs a way to know when to stop. Its method is to read characters until it reaches a newline (\n) character, which you generate by pressing the Enter key. It takes all the characters up to (but not including) the newline, tacks on a null character (\0), and gives the string to the calling program.

这让我很好奇当 gets() 只读入一个换行符时会发生什么。所以我写了这个:

  int main(void)
{
char input[100];

while(gets(input))
{
printf("This is the input as a string: %s\n", input);
printf("Is it the string end character? %d\n", input == '\0');
printf("Is it a newline string? %d\n", input == "\n");
printf("Is it the empty string? %d\n", input == "");
}

return 0;
}

这是我与程序的互动:

$ ./a.out
This is some string
This is the input as a string: This is some string
Is it the string end character? 0
Is it a newline string? 0
Is it the empty string? 0

This is the input as a string:
Is it the string end character? 0
Is it a newline string? 0
Is it the empty string? 0

当我只按回车键时,第二个 block 真的很有趣。在这种情况下,input 到底是什么?这似乎不是我的任何猜测:\0\n""

最佳答案

gets 的描述中的这一部分可能会令人困惑:

It takes all the characters up to (but not including) the newline

最好说它接受所有包括换行符的字符,但存储所有不包括的字符strong>换行符。

因此,如果用户输入some stringgets 函数将从用户终端读取some string 和换行符,但存储缓冲区中只有 some string - 换行符丢失了。这很好,因为反正没有人想要换行符 - 它是一个控制字符,而不是用户想要输入的数据的一部分。

因此,如果您只按entergets 会将其解释为空字符串。现在,正如一些人所指出的,您的代码有多个错误。


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 转换为 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相反,即使它不太方便:

char input[100];
while (fgets(input, sizeof input, stdin))
{
...
}

这可能会导致混淆:fgets 不会从它读取的输入中删除换行字节。因此,如果您将代码中的 gets 替换为 fgets,您将得到不同的结果。幸运的是,您的代码将以清晰的方式说明差异。

关于c - gets() 只读取一个换行符时保存了什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32757162/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com