【问题标题】:How do I check if a value matches a string如何检查值是否与字符串匹配
【发布时间】:2010-12-08 13:52:55
【问题描述】:

我在这里有一个结构,类似于:

char *sname;
........
players[i].sname

相当于“詹姆斯”。

我需要像这样检查值之间的相等性:

if (players[i].sname == 'Lee')

但我运气不好。是否有我应该使用的str* 函数,或者无论如何可以修复我的if 语句?

【问题讨论】:

标签: c


【解决方案1】:

你应该使用strcmp():

if (strcmp(players[i].sname, "Lee") == 0) { ...

另请注意,C 中的字符串用双引号括起来:""。单个字符用单引号括起来:''。我不确定您的编译器究竟会对'Lee' 做什么,但几乎可以肯定这不是您想要的。

【讨论】:

  • 编译器可能会生成数字0x004c6565。我不确定多字节字符在 C89 中是否合法,但我很确定它们是 C99 的一部分。
  • 多字符整数常量在 C89 及更高版本中是合法的,但它们的值是实现定义的。 ISO/IEC 9899:2011 §6.4.4.4 字符常量:¶10 ... 包含多个字符(例如,'ab')或包含不映射的字符或转义序列的整数字符常量的值对于单字节执行字符,是实现定义的。 … C89 中的措辞本质上是等价的。 (有趣的是,C89 在初始描述中有一个示例 'ab';C99 和 C11 都删除了多字符常量的早期示例。)
【解决方案2】:

您会从标题 <string.h> 中寻找 strcmp()

请注意,您需要一个字符串 — 'Lee' 不是字符串,而是一个多字符常量,这是允许的,但很少有用,尤其是因为表示是由编译器定义的,而不是 C 标准。

如果你想比较两个字符串——调用指向它们的指针firstsecond,然后你写:

if (strcmp(first, second) == 0)    // first equal to second
if (strcmp(first, second) <= 0)    // first less than or equal to second
if (strcmp(first, second) <  0)    // first less than second
if (strcmp(first, second) >= 0)    // first greater than or equal to second
if (strcmp(first, second) >  0)    // first greater than second
if (strcmp(first, second) != 0)    // first unequal to second

在我看来,这清楚地表明了比较是什么,因此应该使用符号。请注意,strcmp() 可以返回任何负值来表示“小于”或任何正值来表示“大于”。

你会找到喜欢的人:

if (strcmp(first, second))    // first unequal to second
if (!strcmp(first, second))   // first equal to second

IMO,它们的优点是简洁,但缺点是不如与零的明确比较清楚。 YMMV.

谨慎使用strncmp() 而不是strcmp(),这是在一个答案中建议的。如果你有:

if (strncmp(first, "command", 7) == 0)

那么如果first 包含"commander",则匹配有效。如果这不是你想要的,但你想使用strncmp(),你会写:

if (strncmp(first, "command", sizeof("command")) == 0)

这将正确拒绝"commander"

【讨论】:

    【解决方案3】:

    简短回答:strcmp()

    长答案:所以你得到了这个:

    if(players[i].sname == 'Lee')
    

    这在几个方面是错误的。首先,单引号在 C 中表示“字符文字”而不是“字符串文字”。

    其次,更重要的是,"string1" == "string2" 不比较字符串,它比较 char *s 或指向字符的指针。它会告诉你两个字符串是否存储在同一个内存位置。这意味着它们是相等的,但错误的结果并不意味着它们是不相等的

    strcmp() 基本上会遍历并比较字符串中的每个字符,在第一个不相等的字符处停止,并返回两个字符之间的差异(这就是为什么你必须说 strcmp() == 0 或 @ 987654330@ 表示平等)。

    还要注意函数strncmp()memcmp(),它们与strcmp() 类似,但更安全。

    【讨论】:

    • 非常感谢 - 我知道有一些根本性的错误。当你从许多部分中不知道哪个部分是错误的时,很难实际查找它:P
    【解决方案4】:

    strcmp 工作正常,只要其中一个字符串以空值结尾。如果两者都是最大长度并且相同,则比较将结束,并且很可能会为相等性测试给出假阴性结果。如果一个字符串被固定在 strcmp 本身的 "" 标记内,那不是问题,因为我们知道它是以 null 结尾的。

    如果我们正在比较两个字符串变量,并且我们不知道它们是否是最大长度(最大长度不是以空结尾的),那么我们需要使用 strncmp,并在其中一个上使用 sizeof 得到第三个参数。这解决了问题,因为 sizeof 知道最大长度。如果其中一个字符串是双引号中的文字,则 strcmp 是 100% 安全的。

    【讨论】:

    • 所有字符串都以 null 结尾。不以 null 结尾的字符序列不是 C 字符串!
    • 字符串字面量始终为您终止。不保证字符数组。如果您只是将 strcpy 放入其中,它们通常是,但有一个例外。如果您有一个 char[20] 数组并尝试在其中放入一个 20 个字符的字符串,则空终止符将在数组之外或不存在。您仍然可以使用数组,因为最大大小是已知的。但是,如果您在这种状态下执行 strcpy,天堂会帮助您。
    猜你喜欢
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    • 1970-01-01
    • 2016-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多