读取字符串并在C中进行比较

4

我正在尝试创建一个基于C语言的字符串菜单,在这个菜单中,用户输入一个命令,然后一段代码块就会运行。

无论我怎么做,条件判断语句始终不成立:

char *input= "";
fgets(input, 50, stdin);
printf("%s",input);
printf("%d",strcmp( input,"arrive\0"));
if(strcmp( input,"arrive\0")==0){....

我相对于c语言还是新手,发现字符串处理非常麻烦。

我做错了什么?

注意:当前的代码会导致程序崩溃 :(


1
请考虑使用strncmp()替代strcmp(),它会为你节省很多麻烦。 - Tim Post
1
为什么strcmp()会引起头痛? - Richard Fox
3
@TimPost的意思是,strcmp()函数完全正常,它执行了它所应该执行的功能——比较两个字符串,在这种情况下似乎很合适。当然,strncmp()函数也完全正常,但它并不能减轻头痛,也不是strcmp()的替代品或更好的选择。 - nos
3个回答

7

为什么strcmp总是返回非0:

strcmp只有在字符串完全相同的情况下才会返回0。为什么它总是返回不同的值呢?这是因为fgets在空字符终止之前在输入缓冲区末尾放置了一个换行符。

/*Will print 0 if you type in arrive<enter>*/
printf("%d",strcmp( input,"arrive\n"));

为什么你的程序会崩溃:

另一个问题是input应该是一个字符缓冲区,像这样:char input[1024];。目前,input是指向只读内存的空终止字符串的指针。


友情建议:

同时不要在字符串字面值中放置空终止符\0。当使用字符串字面值时,它会自动被隐含。对于strcmp来说,双重空终止符并不重要,但它可能会导致你未来的程序出现问题。人们会想知道你为什么要使用双重空终止符。


3
尝试:
#define BUFF_LEN 256

char input[BUFF_LEN];

fgets(input, BUFF_LEN, stdin);

你所拥有的,*input是一个指向未分配内存地址的指针,因此不能被程序使用。在使用它时的结果是未定义的,但通常会导致段错误。如果你想将其作为指针进行访问,你首先需要分配它:
char *input = malloc(BUFF_LEN);

当然,在使用完后,测试它是否失败(NULL),然后释放它。
编辑:
至少根据单一UNIX规范,fgets()保证将缓冲区置空。因此不需要初始化input[]。
正如其他人所说,使用strcmp()时不必包含null / newlines。
我还强烈建议你现在就开始习惯使用strncmp(),以避免未来出现许多问题。

fgets函数所读取的字符数量包括空字符'\0',因此不需要减一(-1)。 - Matthew Flaschen
3
你认为未来可能会出现哪些具体问题?参见strcmp有什么问题? - David Cary

1

尝试将第一行替换为

char input[50];
memset(input, 0, sizeof(input));

编辑: 然而,strcmp不返回0的真正问题是你必须“修剪”从fgets读取的字符串,在大多数情况下,包括换行符。

或者只需使用 char input[50] = {0},而不是浪费周期进行 memset() - Chris Lutz
为什么要对一个将被 fgets 覆盖的缓冲区进行 memset - msw
这只是一种惯例,旨在防止C语言学习者陷入常见陷阱。 - shinkou
@shinkou - 我最初也建议使用它,但是fgets()保证对缓冲区进行空终止。这只是小问题。 - Tim Post

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