提取字符串的第一个字符

3

我正在通过readline()从stdinput中读取字符串,如下:

char * cmdLine = readline();

我希望查看通过readline()生成的字符串的第一个字符是否为感叹号。但是代码

if(cmdLine[0]=="!")

这并不像我想象的那样工作。例如,如果从标准输入中获取的字符串为“!1”,那么它应该是真的。

cmdLine[0]=="!"

如果cmdLine是一个指向字符串的指针,那么我不能用数组括号查看字符串中的每个字符吗?我知道这是一个愚蠢的基础c/指针问题,但这确实让我困扰......

4
你试图将一个整数(cmdLine [0])与一个指针(“!”)进行比较,这应该会产生一个明显的编译器警告。如果没有出现警告,请找出如何将警告级别提高。 - Zan Lynx
这里有另一个问题:你的评论听起来有帮助吗?如果是,那么你是一个比有帮助的人更好的程序员... - nbk
是的,这很有帮助。一旦你打开编译器警告,你就会更早地发现这些问题。这就是为什么编译器警告的原因。 - Zan Lynx
@nbk 如果你想比较字符串中的第一个字符,只需对字符串进行解引用(例如 *string),这相当于评估 string[0],例如 if (*string == '!')(在你解决其他问题之后),并且请注意:单引号括起来的是字符双引号括起来的是字符串 - David C. Rankin
是的,而且gcc编译器的警告非常有说明性。"指针和整数之间的比较"确实是我需要告诉我出了什么问题的答案。别犯二,老铁。如果你知道如何回答一个问题,就直接回答好了。刻薄并不会帮到忙。 - nbk
3个回答

8

"!"更改为'!'。您正在比较一个单个字符与另一个单个字符。

在C语言中,您可以使用单引号指定一个字符。


谢谢!我很感激你的回答。 - nbk

4
你有两个Bug:
  1. 第一个(不太重要)是你正在比较char和指针。element11的答案解决了这个问题。

  2. 第二个(更重要的)Bug是你的构建过程警告级别太低。修复它更加重要,因为它不仅可以帮助你找到Bug 1,而且可能会找到很多其他的Bugs。

如果使用GCC编译器,则如何做取决于你的编译器。使用-Wall -pedantic选项是一个好的开始:
$ gcc -Wall -pedantic test.c
test.c: In function ‘main’:
test.c:7:16: warning: comparison between pointer and integer
  if (cmdLine[0]=="!") {
                ^
test.c:7:16: warning: comparison with string literal results in unspecified behavior [-Waddress]

这里有很好的信息。在C语言中,未定义行为是你最不想要的。C语言通常会继续执行未定义行为,就好像什么坏事都没有发生一样,同时给你意料之外的输出。让编译器捕捉这些问题是一件好事。随着程序规模的增长,未定义行为可能会成为噩梦。 - element11

1
在C语言中,双引号用于表示字符数组。无论您在双引号内输入什么,空字符默认都会被追加到末尾。因此,
"!" // makes for two characters the '!' and the terminating null character '\0'.

您的意图显然是要比较单个字符,单个字符应该用单引号括起来。因此正确的比较方式应该是:

if(cmdLine[0]=='!')

cmdLine[0]=="!"会发生什么?

正如我的答案的第一部分所说,"!"会生成一个以 null 结尾的字符数组或有效字符串。这个(常量)字符串存储在目标文件的数据段中。对 "x" 的引用会给出字符串的起始地址,也就是你会得到一个指针。因此当你执行以下操作时:

 if(cmdLine[0]=='!')

您正在比较一个整数(请注意,char是一种整数类型)和一个指针。尽管这可能不会产生错误(这在[此]答案的第2点中有所说明),但您将无法获得预期的结果。


1
谢谢!我很感激你的回答。 - nbk

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