【问题标题】:C++ Programming, read line from stringC++ 编程,从字符串中读取行
【发布时间】:2014-04-09 10:42:24
【问题描述】:

我需要逐行读取字符串。我尝试了以下代码,但在中间有空行并且无法找到我做错了什么时出现错误。

void ReadAllLine(char *szCont)
{
    int rdl = 0; /* read length */
    int len = 0; /* total length */
    char szLine[512] = {};

    len = strlen(szCont);

    int tl = 0; /* temp len */
    while(rdl < len)
    {  
       sscanf(szCont + rdl, "%512s\r\n", szLine);
       rdl += strlen(szLine) + 1;
       printf("%s\n", szLine);
    }  
    return 0;
}

输入:

#Tag01
ENTRY01
ENTRY02

#Tag02
ENTRY11
ENTRY22

#Tag03
ENTRY31
ENTRY32

输出:

#Tag01
ENTRY01
ENTRY02
#Tag02
ENTRY11
ENTRY22
#Tag03
3
ENTRY31
ENTRY32

为什么这里要打印 3?

注意:每一行都以 Windows 符号 (\r\n) 结束,并且任何行之前或之后都没有空格键。输入从文件中读取并传递给此函数。

【问题讨论】:

  • \r\n 不是“Unix 表示法”,而是 Windows 的。类 Unix 系统使用\n
  • @Jongware ok 更正
  • 你说没有空格但\r\n 不是空格字符?仅供参考all of those are whitespace characters.
  • @legends2k 谢谢你的信息。

标签: c++ string scanf


【解决方案1】:

下面是您的代码,为了重现问题而变得更加简单

#include <cstdio>
#include <cstring>

void ReadAllLine(const char *szCont)
{
    int rdl = 0; /* read length */
    int len = 0; /* total length */
    char szLine[512] = {};

    len = strlen(szCont);

    while(rdl < len)
    {
       sscanf(szCont + rdl, "%s", szLine);
       rdl += strlen(szLine) + 1;
       printf("%s\n", szLine);
    }
}

int main()
{
    const char *str ="\n\n#Tag02";
    ReadAllLine(str);
    return 0;
}

打印出来

#Tag02
2

原因很简单。 sscanf 会忽略空白字符,直到找到非空白字符以推入输出字符串。因此,当您第一次调用sscanf(szCont + 0, "%s", szLine); 时,它会跳过首先出现的2 个\ns,然后继续将#Tag02 推入szLine。现在是rdl = 0 + 7 的值,因为strlen("#Tag02") = 6。这意味着szCont + rdl 现在将指向2,它将在下一次迭代中打印出来。

您的情况也会出现同样的问题;您的输入有 2 个 \n\n 出现,一次在 ENTRY02 之后,然后在 ENTRY22 之后。

【讨论】:

  • 你能帮我把这段代码改成只读取非空行吗?
  • 你以 C++ 的名义使用 C,这太不正确了。当你用 C++ 编程时,遵循 C++ 的做事方式,而不是坚持从 C 继承的旧习惯。有'在 SO 中的许多问题演示了在 C++ 中逐行读取文件。 Here's 不错。
【解决方案2】:

您将回车符 (\r) 和换行符 (\n) 都视为行分隔符,这可能因操作系统而异(如 windows、unix 等),所以要小心,否则,代码看起来好的。除非您在输入上一行时有一些空格,否则不应将“3”作为单独的行出现。 其他选项是在 printf 语句之前使用 fflush,如下所示:

fflush(stdout);
printf("%s\n", szLine);

【讨论】:

  • 每一行都以 unix 表示法 (\r\n) 结束,并且任何行之前或之后都没有空格
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-21
  • 2021-09-13
  • 2012-11-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多