在 C 中使用相等运算符 == 比较两个字符串的相等性 [duplicate]

Using the equality operator == to compare two strings for equality in C [duplicate]

提问人: 提问时间:10/14/2010 最后编辑:Rodrigo de Azevedo 更新时间:7/12/2023 访问量:90208

问:

int main (int argc, **argv)
{
       if (argv[1] == "-hello")
            printf("True\n");
       else
            printf("False\n");
}
# ./myProg -hello
False

为什么?我意识到回报是真的......但是为什么我不能使用相等运算符来比较两个 C 字符串呢?strcmp(argv[1], "-hello") == 0

c 字符串 指针 相等 equality-operator

评论

1赞 JeremyP 10/14/2010
由于您坚持认为该问题是 C 问题,因此我已将 C++ 代码替换为 C 代码。如果你坚持使用std::cout,坚持使用C++标签。
1赞 R.. GitHub STOP HELPING ICE 10/15/2010
当然,这个问题是完全重复的。

答:

22赞 Oliver Charlesworth 10/14/2010 #1

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

6赞 jv42 10/14/2010 #2

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

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

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

评论

4赞 Magnus Hoff 10/14/2010
肯定有一种东西叫做 C 字符串。我不明白你的意思。也许是“C 语言中没有 C 字符串类型”?
0赞 jv42 10/14/2010
那只是在滥用这个词。那里描述的是一个以 null 结尾的字符串,而不是“Pascal String”,后者将大小作为第一个字节。
0赞 jv42 10/14/2010
现在,C 编程语言(如没有 STL 的普通 C++)没有字符串类型。有一个编译器功能,可以自动在双引号“...”之间转换文本添加到常量 char 数组(以 null 结尾),导致在 C/C++ 中处理字符串时出现这个非常常见的错误。
0赞 David Thornley 10/14/2010
还有字符串库函数,它们对 的以 null 结尾的数组进行操作。char
3赞 John Bode 10/15/2010
更准确地说,字符串值由一系列字符表示,后跟一个 0 终止符。这些序列存储为 的数组(字符串文字在 C++ 中存储为 C 的数组)。charcharconst char
3赞 Tom 10/14/2010 #3

因为 C 字符串本身并不存在。它们是以 .\0

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

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

如果你想在词典上进行比较,你总是可以这样做:

#define STR_EQ(s1,s2)    \
   strcmp(s1,s2) == 0

我看到你标记为 C++。因此,您可以这样做:

 std::string arg1 ( argv[1] );
 
 if (arg1 == "-hello"){
    // yeahh!!!
 }
 else{
    //awwwww
 }

评论

0赞 10/14/2010
有人将标签编辑为 C++,这是错误的。现在又回到了 C 语言
0赞 Anthony 10/14/2010 #4

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

评论

1赞 detly 10/14/2010
数组不仅仅是指针,嘿嘿。
0赞 David Thornley 10/14/2010
@detly:很容易犯错误,因为数组几乎会以任何借口衰减为指针。
0赞 John Bode 10/15/2010
@David Thornley:即便如此,最好还是要把术语弄好。C 语言已经足够令人困惑了,而没有弄错基础知识。
0赞 detly 10/15/2010
我的措辞有点刺耳,对不起。但是,事实并非如此。有时候,这种假设真的会咬你。
2赞 kanaka 10/14/2010 #5

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

你真的想使用 strncmp 或类似的东西。

17赞 Bart van Ingen Schenau 10/14/2010 #6

您不能将 C 中的字符串与 == 进行比较,因为 C 编译器对字符串文字之外的字符串一无所知。

编译器看到与任一端的 a 的比较,因此它会执行指针比较(比较指针中存储的地址)char*

1赞 waffle paradox 10/14/2010 #7

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

15赞 pmg 10/14/2010 #8

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

因此,当您拥有数组并在大多数上下文中使用它时,它会衰减为指针:"foobar"

if (name == "foobar") /* ... */; /* comparing name with a pointer */

你希望它什么来比较数组的内容您可以手动执行此操作

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 is not "foobar" */;

评论

1赞 Overdrivr 1/14/2016
if(strcmp(name, "foobar"))如果字符串等效,则计算结果为 false,因为在这种情况下它返回 0。 会更好if (strcmp(name, "foobar") == 0)
0赞 pmg 1/14/2016
感谢您的提醒@Overdrivr。在代码中添加了注释以使其清晰。
5赞 John Bode 10/15/2010 #9

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

除非它是 or 运算符的操作数,或者当它是用于初始化声明中另一个数组的字符串文本时,类型为“N 元素数组 T”的表达式的类型将隐式转换(衰减)为类型“指向 T”,并且表达式的值将是数组第一个元素的地址。sizeof&

所以当你写

if (argv[1] == "-hello")

编译器将表达式从“7元素数组的char”隐式转换为“pointer to char”(已经是指针类型),表达式的值是字符的地址。因此,最终比较的是两个指针值,它们(很可能)永远不会相等,因为并且(很可能)占据了内存中的不同区域。"-hello"argv[1]'-'=="-hello"argv[1]

这就是为什么你必须使用库函数来比较字符串值的原因。strcmp()

评论

0赞 pmg 3/18/2016
在 C 中,字符串值(包括字符串文字)表示为包含 0 终止符的数组......char