【问题标题】:C: Working with strcmp [duplicate]C:使用 strcmp [重复]
【发布时间】:2017-03-13 14:32:37
【问题描述】:

作为一个初学者,我一直在使用库 string.h 的一些函数,并且对函数 strcmp 有一些问题。

我编写了比较两个字符串的程序。如果它们相等,则返回 YESNO,否则返回。

#include <stdio.h>
#include <string.h>

int main() {

    char a[100];
    char b[15] = "hello";

    fgets(a, 100, stdin);

    int compare;

    compare = strcmp(a, b);

    if(compare == 0) {

        printf("YES");
    }
    else {

        printf("NO");
    }

    return 0;
}

运行它后,即使我从键盘输入hello,我也会得到NO。当我添加printf("%d", compare) 行时,结果发现对于任何输入我都会得到1,也就是说,a 中的停止字符大于b 中的停止字符。

我的错误在哪里?

【问题讨论】:

  • 问题不在于strcmp,而在于fgets 的作用和工作原理。
  • @izlin:这意味着 tio 不提供兼容的标准库。
  • @Olaf - 或者在线编译器中的“输入”字段没有在输入中附加换行符:)
  • @Olaf - 您可以通过输入 EOF 而不是换行符来获得一个兼容的环境来表现相同,不是吗?我认为在线编译器只是举例说明即使使用 stdio 工具仍有很多需要考虑的地方。输入流抽象不是完全抽象的。
  • @StoryTeller:好的,我收回我对那个特定平台的评论。想要橙子吗?

标签: c string fgets strcmp


【解决方案1】:

fgets 如果源数组中有足够的空间,则追加与 Enter 键对应的换行符。

您应该在将字符串与另一个字符串进行比较之前删除该字符

a[strcspn( a, "\n" )] = '\0';

例如

#include <stdio.h>
#include <string.h>

int main() {

    char a[100];
    char b[15] = "hello";

    fgets(a, 100, stdin);

    a[strcspn( a, "\n" )] = '\0';

    int compare;

    compare = strcmp(a, b);

    if(compare == 0) {

        printf("YES");
    }
    else {

        printf("NO");
    }

    return 0;
}

【讨论】:

    【解决方案2】:

    这样扫描并没有错,但问题是,fgets() 扫描尾随换行符并将其存储到提供的缓冲区中。如果您将缓冲区与不包含终止换行符的字符串文字进行比较,则需要摆脱它。

    要去除尾随换行符,您可以使用类似

    size_t len = strlen(a);
    if (len > 0 && a[len-1] == '\n') {
        a[--len] = '\0';
    }
    

    See this answer for more reference

    如果不删除换行符,strcmp() 将不会宣布比​​较成功。

    否则,您可以使用strncmp() 并提供字符串字面量的大小,以将比较限制在有效输入。

    【讨论】:

    • strncmp() 不好,除非您还检查输入字符串的长度以确保它与文字字符串一样短,否则(例如)hellohello goodbye 将比较相等.
    • @JeremyP 是的,当然,这就是为什么我提到“仅限于有效输入”
    【解决方案3】:

    fgets(a, 100, stdin); 也将您输入的换行符存储到缓冲区中。因此a 包含"hello\n"。那个额外的字符抵消了比较。

    您可以尝试通过某种方式删除换行符1,或者改为与strncmp 进行比较。


    1. 例如:

      char *newline = strchr(a, '\n');
      if (newline)
        *newline = '\0';
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-17
      • 1970-01-01
      • 2011-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多