20
int main(int argc,**argv){if(argv[1]==“-hello”)printf(“True\n”);其他的printf(“False\n”);}
# ./myProg-你好False(错误)

为什么?我意识到strcmp(argv[1],“-hello”)==0返回true。。。但是为什么我不能用相等操作符来比较两个C字符串呢?

2
  • 1
    既然你坚持这个问题是C问题,我就用C代码代替了C++代码。如果你坚持性病::cout,坚持使用C++标记。 评论 2010年10月14日14:44
  • 1
    当然,这个问题是完全重复的。 评论 2010年10月15日2:30

9个答案9

重置为默认值
22

因为argv[1](argv[1])(例如)实际上是指向字符串的指针。所以您所做的只是比较指针。

17

您不能将C中的字符串与==进行比较,因为C编译器除了字符串文字之外,对字符串没有任何线索。

编译器看到与字符*在每一侧,它都会进行指针比较(比较指针中存储的地址)

15

C类因为在大多数情况下,数组“衰减为指向其第一个元素的指针”。

所以,当你有了数组“foobar”在大多数情况下使用,它会衰减为指针:

if(name==“foobar”)/*…*/;/*将名称与指针进行比较*/

您希望它与数组的内容具有某物。您可以手动执行此操作

if('p'==*(“foobar”))/*…*/;/*false:'p'!='f’*/if('m'==*(“foobar”+1))/*…*/;/*false:'m'!='o’*/if('g'==*(“foobar”+2))/*…*/;/*false:'g'!='o’*/

或自动

if(strcmp(name,“foobar”))/*name不是“fooba”*/;
2
  • 1
    if(strcmp(名称,“foobar”))如果字符串等效,则将计算为false,因为在这种情况下它返回0。if(strcmp(name,“foobar”)==0)会更好
    – 超速档
    评论 2016年1月13日17:46
  • 感谢@Overdrivr的提醒。在代码中添加注释以使其清晰可见。 评论 2016年1月14日10:15
6

因为没有C字符串这样的东西。

在C语言中,字符串通常是一个char数组,或指向char的指针(这几乎相同)。将指针/数组与常量数组进行比较不会得到预期的结果。

更新:我所说的“无C字符串”是指C中没有字符串。通常称为“C字符串”的是与语言无关的(如“Pascal字符串”),它是字符串的表示,是一个以null结尾的线性字符数组。

5
  • 4
    绝对有一种东西叫做C字符串我不知道你到底是什么意思。也许是“C语言中没有C字符串类型”? 评论 2010年10月14日14:05
  • 那只是滥用了这个词。所描述的是一个以null结尾的字符串,而不是“Pascal string”,它给出了第一个字节的大小。
    – jv42型
    评论 2010年10月14日14:17
  • 现在,C编程语言(就像没有STL的普通C++一样)没有字符串类型。有一个编译器功能可以自动将双引号“…”之间的文本转换为常量字符数组(以null结尾),从而导致在C/C++中处理字符串时出现这种非常常见的错误。
    – jv42型
    评论 2010年10月14日14:19
  • 还有一些字符串库函数,它们操作以null结尾的数组烧焦. 评论 2010年10月14日15:50
  • 更恰当地说,字符串值是代表由一系列字符组成,后跟一个0终止符。这些序列存储为烧焦(字符串字面量存储为数组烧焦以C为单位,常量字符(在C++中)。 评论 2010年10月14日16:35
5

在C语言中,字符串值(包括字符串文字)表示为烧焦后面跟一个0终止符,并且不能使用==运算符比较数组内容;语言根本没有定义操作。

除非它是大小&运算符,或者当它是用于初始化声明中另一个数组的字符串文字时,类型为“N元素数组T”的表达式将其类型隐式转换(衰退)为类型“指针到T”,表达式的值将是数组第一个元素的地址。

所以当你写的时候

if(argv[1]==“-hello”)

编译器隐式转换表达式“-你好”从类型“char的7元素数组”到“char指针”(argv[1](argv[1])已经是指针类型),表达式的值为地址角色的'-'.那又怎么样==最后比较两个指针值,自“-你好”argv[1](argv[1])(很可能)占用内存中的不同区域。

这就是为什么您必须使用库函数,如strcmp()比较字符串值。

1
  • 在C语言中,字符串值(包括字符串文字)表示为烧焦 其中包括0终止符。。。 评论 2016年3月17日16:33

因为C字符串并不是这样存在的。它们是以\0.

相等运算符==将测试指向数组第一个元素的指针是否相同。它不会进行词典比较。

另一方面“-hello”==“-hello” 可以返回非零,但这并不意味着==运算符按字典顺序进行比较。这是由于其他事实。

如果你想按字典顺序进行比较,你可以这样做:

#定义STR_EQ(s1,s2)\strcmp(s1,s2)==0

我看到你被标记为C++。所以你可以这样做:

标准::字符串arg1(argv[1]);if(arg1==“-hello”){//耶!!!}其他{//哎哟}
1
  • 有人将标签编辑为C++,这是错误的。现在又回到C了
    – 用户402642
    评论 2010年10月14日13:52
2

字符串在C中不是本机类型。您在该示例中比较的是两个指针。一个是第一个参数,另一个是包含“-hello”内容的静态字符数组。

您确实想使用strncmp或类似的东西。

1

当您使用==时,您是在比较指针。也就是说,如果两个操作数引用内存中的同一字符串,则返回true。因此,它不适合用于按字典顺序比较字符串。

0

因为C字符串是字符数组。数组只是指向数组中第一个元素的指针,当使用==比较两个指针时,它会比较它们指向的内存地址,而不是它们指向的值。

4
  • 1
    数组不仅仅是指针,害羞。
    – 详细地
    评论 2010年10月14日13:32
  • @detly:考虑到数组在几乎任何借口下都会退化为指针,很容易犯错误。 评论 2010年10月14日15:51
  • @大卫·桑利:即便如此,最好还是要把术语弄对。C语言在不弄错基础知识的情况下已经足够令人困惑了。 评论 2010年10月14日16:56
  • 对不起,我的措辞有点苛刻。但事实并非如此。有时,这种假设会真正刺痛你。
    – 详细地
    评论 2010年10月15日3:23