简体   繁体   English

C ++编程,从字符串读取行

[英]C++ Programming, read line from string

I need to read line by line from a string. 我需要从字符串中逐行读取。 I tried the following code but I am getting a error while there are empty lines in between and not able to find what I am doing wrong. 我尝试了以下代码,但是当它们之间有空行时却出现错误,并且找不到我在做什么。

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;
}

Input : 输入:

#Tag01
ENTRY01
ENTRY02

#Tag02
ENTRY11
ENTRY22

#Tag03
ENTRY31
ENTRY32

Output : 输出:

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

why is the 3 getting printed here? 为什么在这里打印3个?

Note : Every line is terminated with Windows notation (\\r\\n) and there are no spacebars before or after any line. 注意:每行以Windows表示法(\\ r \\ n)终止,并且在任何一行之前或之后都没有空格键。 The input is read from a file and passed to this function. 从文件中读取输入,并将其传递给此函数。

Below is your code made even more minimal to reproduce the issue 下面是使您的代码最小化以重现该问题的方法

#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;
}

This prints 此打印

#Tag02
2

The reason is quite simple. 原因很简单。 sscanf ignores whitespace characters until it finds non-whitespace characters to push in to the output string. sscanf忽略空白字符,直到找到非空白字符以将其压入输出字符串为止。 Thus, when you call sscanf(szCont + 0, "%s", szLine); 因此,当您调用sscanf(szCont + 0, "%s", szLine); for the first time, it skips the 2 \\n s occuring first and then moves on to pushing #Tag02 into szLine . 第一次,它跳过第一次出现的2 \\n ,然后继续将#Tag02推入szLine Now the value of rdl = 0 + 7 since strlen("#Tag02") = 6 . 现在,因为strlen("#Tag02") = 6的值rdl = 0 + 7 This means szCont + rdl would now be pointing to 2 , which gets printed in the next iteration. 这意味着szCont + rdl现在将指向2 ,它将在下一次迭代中显示。

The same issue occurs in your case too; 您的情况也会发生相同的问题; your input has 2 \\n\\n ocurrings, once after ENTRY02 , then after ENTRY22 . 您的输入有2次\\n\\n ,一次是在ENTRY02之后,然后是在ENTRY22之后。

You are treating carriage return (\\r) and line feed (\\n) both as line separators, this may vary from operating system to operating system (like windows, unix etc), so be careful, otherwise, the code looks ok. 您将回车符(\\ r)和换行符(\\ n)都视为行分隔符,这可能因操作系统而异(例如Windows,Unix等),因此请小心,否则代码看起来还可以。 There should not be '3' coming as a separate line, unless you have some whitespace while inputting previous line. 除非您在输入前一行时有一些空格,否则不应将“ 3”作为单独的行出现。 Other option is to use fflush before printf statement as below: 另一种选择是在printf语句之前使用fflush,如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM