我需要从字符串中逐行读取。我尝试了以下代码,但我遇到了一个错误,因为中间有空行,无法找到我做错了什么。
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, "%512srn", szLine);
rdl += strlen(szLine) + 1;
printf("%sn", 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)终止,并且在任何一行之前或之后都没有空格键。输入从文件中读取并传递给此函数。
下面是您的代码,使其更加最小化,以再现问题
#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("%sn", szLine);
}
}
int main()
{
const char *str ="nn#Tag02";
ReadAllLine(str);
return 0;
}
这将打印
#Tag02
2
原因很简单。sscanf
忽略空白字符,直到它找到非空白字符以推送到输出字符串。因此,当您第一次调用sscanf(szCont + 0, "%s", szLine);
时,它会跳过首先出现的2个n
,然后继续将#Tag02
推入szLine
。现在是CCD_ 6自CCD_。这意味着szCont + rdl
现在将指向2
,它将在下一次迭代中打印出来。
同样的问题也发生在你的案例中;您的输入有两个nn
提示,一次在ENTRY02
之后,然后在ENTRY22
之后。
您将回车(\r)和换行(\n)都视为行分隔符,这可能因操作系统(如windows、unix等)而异,所以要小心,否则代码看起来不错。不应该有"3"作为单独的行出现,除非您在输入前一行时有一些空格。另一种选择是在printf语句之前使用fflush,如下所示:
fflush(stdout);
printf("%sn", szLine);