strcmp 在使用 fgets 读取的行上

发布于 2024-08-25 02:34:51 字数 349 浏览 6 评论 0原文

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

下面是一个示例程序:

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

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

    return 0;
}

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

I'm trying to compare two strings. One stored in a file, the other retrieved from the user (stdin).

Here is a sample program:

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

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

    return 0;
}

In this program, strcmp returns a value of -1 when the input is "bob".
Why is this? I thought they should be equal. How can I get it so that they are?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

时光倒影 2024-09-01 02:34:52

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

Mostly because of the end of line char in the input "\n" under unix like system.

累赘 2024-09-01 02:34:51

strcmp 是少数几个具有 true 和 false 相反结果的函数之一...如果字符串相等,结果是 0,而不是您想象的 1...

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

说到 < code>fgets,字符串末尾可能有一个换行符...您需要删除它...

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

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

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

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

现在,strcmp 应返回 0 ...

strcmp is one of the few functions that has the reverse results of true and false...if the strings are equal, the result is 0, not 1 as you would think....

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

Speaking of fgets, there is a likelihood that there is a newline attached to the end of the string...you need to get rid of it...

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

To get rid of the newline do this.
CAVEATS: Do not use "strlen(aName) - 1", because a line returned by fgets may start with the NUL character - thus the index into the buffer becomes -1:

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

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

Now, strcmp should return 0...

九局 2024-09-01 02:34:51

fgets 会一直读取,直到看到换行符然后返回,因此当您在控制台中键入 bob 时,targetName 包含“bob\n”,与“bob”不匹配。
来自 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));

fgets reads until it sees a newline then returns, so when you type bob, in the console, targetName contains "bob\n" which doesn't match "bob".
From the fgets documenation: (bolding added)

Reads characters from stream and stores them as a C string into str until (num-1) characters have been read or either a newline or a the End-of-File is reached, whichever comes first.
A newline character makes fgets stop reading, but it is considered a valid character and therefore it is included in the string copied to str.
A null character is automatically appended in str after the characters read to signal the end of the C string.

You need to remove the newline from the end of targetName before you compare.

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

or add the newline to your test string.

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

char aName[] = "bob\n";
printf("%d",strcmp(aName,targetName));
赠意 2024-09-01 02:34:51

fgets 将 \n 附加到用户按 Enter 时从用户那里拉取的字符串。您可以通过使用 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)

这只是将 \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)

但它并不那么优雅。

The fgets is appending a \n to the string that you are pulling in from the user when they hit Enter. You can get around this by using strcspn or just adding \n onto the end of your string you're trying to compare.

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)

This just replaces the \n with a \0, but if you want to be lazy you can just do this:

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)

But it's not as elegant.

秋意浓 2024-09-01 02:34:51

因为 fgets 将换行符嵌入到变量 targetName 中。这就失去了比较的意义。

Because fgets is embededing the newline character into the variable targetName. This is throwing off the comparison.

当梦初醒 2024-09-01 02:34:51

fgets 将换行符附加到字符串中,因此最终会得到 bob\n\0 ,它与 bob\0 不同>。

fgets appends the newline to the string, so you'll end up with bob\n\0 which isn't the same as bob\0.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文