【问题标题】:equivalent of fgets on a buffer?相当于缓冲区上的 fgets?
【发布时间】:2011-09-17 15:44:26
【问题描述】:

我最初是使用fgets() 逐行解析文件。

现在我改变了一些东西,以便我已经将整个文件放在缓冲区中。我仍然喜欢逐行读取该缓冲区以进行解析。是否有为此设计的东西,还是我需要创建一个循环来检查0x0Achars?

【问题讨论】:

  • 如果您使用 C++,请查看istringstream,它允许您“从内存中的字符串读取”。
  • 您已标记此 cc++ ... 它是什么?你的缓冲区是如何定义的?
  • 决定您是要编写 C 代码还是 C++ 代码。然后回来问怎么做。我不会浪费时间为您编写 C++ 解决方案,因为您可能会认为它“C 不够用”。
  • 我正在使用 C++,但我更喜欢使用像 fopen 这样的 C 函数,因为使用它们很容易实现。
  • 如果您编写词法分析器,为什么不将其写入flex,它的速度非常快,而且每次都正确。它将为您提供 C 和 C++ 输出,并且您可以在收到令牌后编写回调来表达您的心意。

标签: c++ c io fgets


【解决方案1】:

memchr(带有一点你自己的包装代码,以memcpy结尾)是完全等价的——就像fgets一样,它需要一个最大的长度来处理(应该是剩余输入缓冲区的最小值大小和输出缓冲区的大小)并扫描,直到找到所需的字符(将是'\n')或用完输入/输出空间。

请注意,对于已经在内存缓冲区中的数据,您可能希望跳过复制到单独的输出缓冲区的步骤,除非您需要在不修改输入的情况下以空值终止输出。许多初学者 C 程序员经常犯错误认为他们需要空终止,而实际上只需改进一些接口以采用 (pointer, length) 对就足够了,允许您传递/处理子字符串而不复制它们。例如,您可以将它们传递给printf,使用:printf("%.*s", (int)length, start);

【讨论】:

  • 感谢您指出memchr。我从来没有用过它,但我以前用过strrchr,这很方便。谢谢
【解决方案2】:

您可以为此使用sscanf 函数。如果你真的需要一整行,这样的事情应该可以解决问题:

sscanf(your_buffer, "%50[^\n]", line);

(这将读取最多 50 个字符长的行。与往常一样,请注意长度和 0 终止符。并检查 sscanf 的返回值以防出现问题。)

您可以使用指针算法来移动缓冲区(只需添加“返回的”行长度 + 1)。

【讨论】:

    【解决方案3】:

    有 sscanf 可能对你有用,也可能对你没用。

    【讨论】:

    • 似乎 sscanf 没有为我提供一个指向匹配字符串末尾的指针。我仍然需要进行搜索。
    • 它返回处理的字节数。
    • 我很确定它会返回匹配的数量。
    【解决方案4】:

    如果您正在寻找 C 函数,strtok()strsep() 都会在指定字符上拆分字符串。

    【讨论】:

    • 我确定strtok 会修改底层字符串,这可能并不适合该任务,strstep 呢?
    • 是的,这两个函数都修改了字符串。如果你不想这样做,你需要用 strchr / memcpy 做点什么。
    【解决方案5】:

    对于 C,我认为这应该可行:

    // str (in/out): the unconsumed portion of the input string
    static char *sgets(char *buf, int n, const char **str)
    {
        const char *s = *str;
        const char *lf = strchr(s, '\n');
        int len = (lf == NULL) ? strlen(s) : (lf - s) + 1;
    
        if (len == 0)
            return NULL;
        if (len > n - 1)
            len = n - 1;
    
        memcpy(buf, s, len);
        buf[len] = 0;
        *str += len;
        return buf;
    }
    

    【讨论】:

      猜你喜欢
      • 2017-04-07
      • 2010-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多