【问题标题】:Using the equality operator == to compare two strings for equality in C [duplicate]使用相等运算符 == 在 C 中比较两个字符串是否相等 [重复]
【发布时间】:2011-04-25 10:03:59
【问题描述】:
int main (int argc, **argv)
{
       if (argv[1] == "-hello")
            printf("True\n");
       else
            printf("False\n");
}
# ./myProg -你好 错误的

为什么?我知道strcmp(argv[1], "-hello") == 0 返回 true... 但是为什么我不能使用相等运算符来比较两个 C 字符串?

【问题讨论】:

  • 既然你坚持这个问题是一个 C 问题,我已经用 C 代码替换了 C++ 代码。如果你坚持使用 std::cout,I 坚持使用 C++ 标签。
  • 这个问题肯定是完全重复的。

标签: c string pointers equality equality-operator


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

    更新:我所说的“没有 C 字符串”的意思是,C 中没有字符串。通常所说的“C 字符串”与语言无关(就像“Pascal 字符串”一样),它是字符串的表示形式作为一个以空字符结尾的线性字符数组。

    【讨论】:

    • 肯定有一个东西叫做C string。我不知道你到底是什么意思。也许是“C 语言中没有 C 字符串类型”?
    • 这只是滥用术语。所描述的是一个以 null 结尾的字符串,而不是一个“Pascal 字符串”,它将大小作为第一个字节。
    • 现在,C 编程语言(作为没有 STL 的普通 C++)没有字符串类型。有一个编译器功能可以自动将双引号“...”之间的文本转换为常量 char 数组(以 null 结尾),导致在 C/C++ 中处理字符串时出现这种非常常见的错误。
    • 还有字符串库函数,对char的空终止数组进行操作。
    • 更准确地说,一个字符串值表示由一个字符序列后跟一个 0 终止符。这些序列存储为char 的数组(字符串literals 在C 中存储为char 的数组,在C++ 中存储为const char)。
    【解决方案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
     }
    

    【讨论】:

    • 有人将标签编辑为C++,这是错误的。现在又回到了 C
    【解决方案4】:

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

    【讨论】:

    • @detly:很容易犯错误,考虑到数组几乎可以以任何借口衰减为指针。
    • @David Thornley:即便如此,最好还是让术语正确。 C 语言已经够令人困惑了,但基本不会出错。
    • 我的措辞有点苛刻,抱歉。但是,事实并非如此。有时候,这种假设真的会咬你一口。
    【解决方案5】:

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

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

    【讨论】:

      【解决方案6】:

      您不能将 C 中的字符串与 == 进行比较,因为 C 编译器对于字符串文字之外的字符串并没有真正的线索。

      编译器在任一侧看到与char* 的比较,因此它进行指针比较(比较存储在指针中的地址)

      【讨论】:

        【解决方案7】:

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

        【讨论】:

          【解决方案8】:

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

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

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

          你想让它比较 数组的内容something。您可以手动执行此操作

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

          【讨论】:

          • 如果字符串等价,if(strcmp(name, "foobar")) 将评估为 false,因为在这种情况下它返回 0。 if (strcmp(name, "foobar") == 0) 会更好
          • 感谢@Overdrivr 的提醒。在代码中添加注释以使其清晰。
          【解决方案9】:

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

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

          所以当你写的时候

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

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

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

          【讨论】:

          • 在 C 中,字符串值(包括字符串文字)表示为 char 的数组其中包括一个 0 终止符 ...
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-01-05
          • 2023-04-10
          • 2016-08-10
          • 2014-07-19
          • 1970-01-01
          相关资源
          最近更新 更多