9

我正在尝试比较两个字符串。一个存储在文件中,另一个从用户(stdin)中检索。

这是一个示例程序:

int main()
{
    char targetName[50];
    fgets(targetName,50,stdin);

    char aName[] = "bob";
    printf("%d",strcmp(aName,targetName));

    return 0;
}

在此程序中,strcmp当输入为 时,返回值 -1 "bob"。为什么是这样?我认为他们应该是平等的。我怎样才能得到它,使他们是?

4

6 回答 6

12

strcmp是少数几个具有真假相反结果的函数之一……如果字符串相等,则结果为 0,而不是您想象的 1……

if (strcmp(a, b)) {
    /* Do something here as the strings are not equal */
} else {
    /* Strings are equal */
}

说到fgets,字符串末尾可能有一个换行符......你需要摆脱它......

+-+-+-+--+--+
|b|o|b|\n|\0|
+-+-+-+--+--+

要摆脱换行符,请执行此操作。注意事项:不要使用“strlen(aName) - 1”,因为 fgets 返回的行可能以 NUL 字符开头 - 因此缓冲区的索引变为 -1:

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

+-+-+-+--+
|b|o|b|\0|
+-+-+-+--+

现在,strcmp应该返回 0...

于 2010-03-08T21:21:43.400 回答
7

fgets读取直到看到换行符然后返回,因此当您在控制台中键入 bob 时,targetName包含与“bob”不匹配的“bob\n”。来自 fgets 文档:(添加粗体)

从流中读取字符并将它们作为 C 字符串存储到 str 中,直到读取 (num-1) 个字符或到达换行符或文件结尾,以先到者为准。 换行符使 fgets 停止读取,但它被认为是有效字符,因此它包含在复制到 str 的字符串中。 在读取的字符之后会在 str 中自动附加一个空字符,以表示 C 字符串的结束。

在比较之前,您需要从 targetName 末尾删除换行符。

int cch = strlen(targetName);
if (cch > 1 && targetName[cch-1] == '\n')
   targetName[cch-1] = '\0';

或将换行符添加到您的测试字符串中。

char targetName[50];
fgets(targetName,50,stdin);

char aName[] = "bob\n";
printf("%d",strcmp(aName,targetName));
于 2010-03-08T21:20:44.050 回答
3

当用户按下 Enter 键时,fgets 会将 a 添加\n到您从用户那里拉入的字符串中。您可以通过使用strcspn或只是添加\n到您尝试比较的字符串的末尾来解决这个问题。

printf("Please enter put FILE_NAME (foo1, 2, or 3), ls, or exit: \n");
fgets(temp, 8, stdin);
temp[strcspn(temp, "\n")] = '\0';
if(strcmp(temp, "ls") == 0 || strcmp(temp, "exit") == 0)

这只是用 a 替换\n\0,但如果你想偷懒,你可以这样做:

printf("Please enter put FILE_NAME (foo1, 2, or 3), ls, or exit: \n");
fgets(temp, 8, stdin);
if(strcmp(temp, "ls\n") == 0 || strcmp(temp, "exit\n") == 0)

但它没有那么优雅。

于 2012-08-30T15:54:54.640 回答
2

因为 fgets 将换行符嵌入到变量targetName中。这是抛弃比较。

于 2010-03-08T21:17:51.300 回答
1

fgets将换行符附加到字符串中,因此您最终会bob\n\0得到与bob\0.

于 2010-03-08T21:18:12.883 回答
1

主要是因为在类unix系统下输入“\n”中的行尾字符。

于 2010-03-08T21:19:45.027 回答