strcmp无法工作

12

我知道这可能是一个非常新手的问题(我已经很久没有接触C语言了),但有人可以告诉我为什么这不起作用吗?

printf("Enter command: ");
bzero(buffer,256);
fgets(buffer,255,stdin);

if (strcmp(buffer, "exit") == 0)
    return 0;
如果我输入“exit”,它不会进入if语句,这与“buffer”的长度有关吗?
您有什么建议吗?
5个回答

30
你想要做的是: strcmp(buffer, "exit\n") 也就是说,当你输入字符串并按下“回车”键时,换行符会成为buffer的一部分。
或者,使用strncmp(),它只比较字符串的前n个字符。

4
如果用户在“退出”前或后输入了空格,那就不好了。还有一个(可能是虚构的)故事,讲的是当厄瓜多尔被添加进去时系统停止工作了——人们必须输入首都基多的名称“Quito”,但程序只与“quit”比较前四个字母,因此程序退出(quit)。相当糟糕! - Jonathan Leffler
3
我的建议是确保用户无法向您的程序输入任何内容。 - poundifdef

10

fgets() 返回字符串 "exit\n",与 gets() 不同,它保留换行符。


...而且“gets”只需要一个参数(在这个例子中是缓冲区)。谢谢! - juan
9
(请不要在公共场合使用 gets()。) 建议翻译:请勿在公开场合使用 gets() 。 - Dave
2
@Jian,因为gets()函数无法防止缓冲区溢出。 - Paul Tomblin

6
正如其他人所说,与"exit"进行比较失败是因为fgets()将换行符包含在缓冲区中。其中一个保证是,除非输入的行太长而无法放入缓冲区,否则缓冲区将以换行符结尾。fgets()还保证缓冲区以空字符结尾,因此您不需要清零256个字节,只需让fgets()使用255个字节即可获得该保证。
直接比较是否为"exit\n"的简单答案要求用户不会在单词前后意外添加空格。如果您想强制用户小心使用退出命令,则可能无关紧要,但总体上可能会成为用户烦恼的原因。
使用strncmp()可能会使"exited""exit42"等匹配,这可能会对您产生负面影响,特别是如果某些有效命令是其他有效命令的前缀字符串时。
通常情况下,将I/O、分词、解析和操作分别处理是一个好主意。

使用:fgets(buffer, sizeof(buffer), fp); 不要减去1(或使用255),因为fgets()表现得很正常 - 您告诉它有多少空间,它确保不使用更多空间,在数组中的最后一个可用字符中放置空终止符。 - Jonathan Leffler
正是我想说的...但表达得更好。;-) - RBerteig

1

1

我建议您从字符串末尾删除 \n,像这样。

char buf[256];
int len;
/* 获取字符串,确保留有空间用于空字节 */
if ( fgets(buf,sizeof(buf) - 1) == EOF )
{
  printf("错误\n");
  exit(1);
}
/* 绝对始终以空字符结尾,简单易行 */
buf[sizeof(buf) - 1] = '\0';
/* 计算长度,并截断任何 \n */
len = strlen(buf);
while ( len > 0 && buf[len - 1] == '\n' )
{
  buf[len - 1] = '\0';
  --len;
}

这样,如果您必须将输入的字符串与多个常量进行比较,则不必将 \n 添加到所有常量中。


为什么要downvote?虽然没有解释,但它是一个有效的解决方案。 - Mihai Maruseac

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接