【问题标题】:C - getline() and strcmp() issueC - getline() 和 strcmp() 问题
【发布时间】:2015-04-01 18:05:01
【问题描述】:

我遇到了一个问题,使用 getline 时,我无法使用 strcmp() 在文件中找到特定单词。

我的文件看起来像这样:

Word1
Word2
Word3
section1
Word4

这是我现在的代码:

while(found == 0)
{
    getline(&input, &len, *stream);
    if (feof(*stream))
        break;

    if(strcmp(input, "section1\n") == 0)
    {
        printf("End of section\n");
        found = 1;
    }
}

strcmp() 永远不会返回 0。任何见解将不胜感激!

对代码进行了编辑。我转错了。

来自 cmets 的解决方案: 我需要将 \r 添加到正在比较的字符串中

if(strcmp(input, "section1\r\n") == 0)

【问题讨论】:

  • BLUEPIXY 提到的还有,您是在 Windows 上执行此操作(换行符是 \r\n)吗?
  • 您的文件是否使用\r\n 结尾?此外,您的 if 表达式中缺少括号,因此不应编译...
  • @iharob 因为他想在找到该行时跳出,而不是处理文件的其余部分,大概
  • 什么是stream?如果是FILE* stream;,那么getline/feof 的参数不应该是*stream,而应该是stream
  • 请发布这个甚至无法编译的真实代码。

标签: c getline strcmp


【解决方案1】:

删除潜在的行尾字符,然后进行比较。

getline(&input, &len, *stream);
input[strcspn(input, "\r\n")] = 0;
if(strcmp(input, "section1") == 0)
{
    printf("End of section\n");
    found = 1;
}

注意:对于getline(),缓冲区以空值结尾并包括换行符(如果找到的话)。明智地检查来自getline() 的返回值。

【讨论】:

  • 由于getline()返回它读取的行中的字符数,您可以通过捕获返回值来加快换行的删除。
  • @Jonathan Leffler True 关于加速使用各种代码和len。虽然通常加速比花在getline() 本身的时间相形见绌。 Trimming fgets(): strlen() or strtok()
【解决方案2】:

在这种情况下,您不需要使用feof。您正在使用 getlinestrcmp 来测试线路。使用getline的返回来测试是否继续阅读。正确的实现类似于:

while (getline(&input, &len, *stream) != -1)
{
    if(strcmp (input, "section1\n") == 0)
    {
        printf("End of section\n");
        found = 1;
        break;  /* if you want to terminate read when found=1 */
    }
}

要消除在读取的每行末尾悬空newlines 的问题,只需将其删除即可。 getline 使这变得非常简单,因为它返回实际读取的字符数——无需调用 strlen。只需在变量中捕获getline 的返回值,然后删除newline(或carriage returnnewline,如果使用DOS 行结束)如下:

ssize_t nchr = 0;   /* number of characters actually read */

while ((nchr = getline (&input, &len, *stream)) != -1)
{
    /* strip trailing '\n' or '\r' */
    while (nchr > 0 && (input[nchr-1] == '\n' || input[nchr-1] == '\r'))
        input[--nchr] = 0;
    ...

【讨论】:

  • 很高兴看到代码检查 getline() 结果并在 while 循环中测试 read > 0,经常错过两件事。 +1
  • valgrind 太多 invalid read of size 1 错误,无法检查 read > 0。看,即使是盲松鼠也能偶尔找到一颗坚果:p
  • 'read' 是系统函数的名称。变量名不应使用系统函数名。
  • 关于这一行:'if(strcmp(input, "section1\n") == 0)' 代码可以通过使用:'if(strncmp(input, "section1" , sizeof "section1") == 0)'
  • 那行不通。您必须从sizeof literal 中减去1,否则您将在计数中包含null-terminating 字符。使用-1,这是一个很大的改进 - 以及您对read 的捕获。修复。
猜你喜欢
  • 2014-11-22
  • 2013-05-12
  • 1970-01-01
  • 2011-06-09
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多