fscanf在空间中读取分隔数据直到返回

时间:2014-02-26 18:07:00

标签: c delimiter scanf eol

我试图从txt文件中读取数据。 txt文件有多个条目,每个条目占用一个新行,每个条目具有由一些符号(例如空格'')分隔的可变长度的十六进制字节数据。示例txt文件如下所示

e4 e2 e2 e1 ff\n
f2 a2 22 34\n
ff ee dd\n

在循环中使用scanf(fp,“%2x”,缓冲区+偏移量),我试图将每个字节加载到字节缓冲区中,直到每行结束,标记完整记录。主要问题是检测换行符,因为scanf完全忽略它并跳转到下一行。我的原始代码是

do{
    counter=fscanf(datain,"%2x",buffer1+offset);
    fprintf(stdout,"%#2x ",buffer1[offset]);
    offset+=counter;
}while(!feof(datain));

2 个答案:

答案 0 :(得分:2)

另一种通常更简单的方法是使用fgets()getline()阅读整行,然后使用sscanf()处理该行上的符号。在许多方面,这与当前方案类似,但您需要能够在字符串中前进,因此%n转换规范通常在这里有用:

while (fgets(line, sizeof(line), datain) != 0)
{
    int line_offset = 0;
    int new_offset;
    while (sscanf(line + line_offset, "%2x%n", &buffer1[offset], &new_offset) == 1)
    {
        printf("%#.2x ", buffer1[offset]);
        offset++;
        line_offset += new_offset;
    }
}

%n转换不会计入sscanf()的回复中。

请注意,这可以避免在另一个answer中看到的其他一些问题。当没有要读取的行时,它不会尝试处理数据,并且当没有任何行时,它不会尝试处理数据。

此外,一次读取一行的优点之一是,当您可以将整个上下文(行)放在发生错误的位置时,错误报告通常更容易/更好,而不是停留在行的左侧经过一些不确定的成功转换后。如果该行的第六个字段中存在错误字符,则可以显示前五个字段以及错误的位置。

答案 1 :(得分:0)

通过在每个十六进制说明符后附加%c,我可以从流中提取空格和换行符。通过测试这个角色,我可以知道已经达到了一条新线。

do{
    counter=fscanf(datain,"%2x%c",buffer1+offset,&followsymbol);
    fprintf(stdout,"Counter:%i\n",counter);
    if (counter==2)
         {fprintf(stdout,"data:%5x\tfollowsymbol:%5x\n",buffer1[offset],followsymbol);
          offset+=1;
         }
    if(followsymbol==0x0a && counter==2)
          printf("a nl symbol has been detected\n");
}while(!feof(datain));

终端的输出

Counter:2
data:ffffffe4   followsymbol:   20
Counter:2
data:ffffffe2   followsymbol:   20
Counter:2
data:ffffffe2   followsymbol:   20
Counter:2
data:ffffffe1   followsymbol:   20
Counter:2
data:ffffffff   followsymbol:    a
a nl symbol has been detected
Counter:2
data:fffffff2   followsymbol:   20
Counter:2
data:ffffffa2   followsymbol:   20
Counter:2
data:   22      followsymbol:   20
Counter:2
data:   34      followsymbol:    a
a nl symbol has been detected
Counter:2
data:ffffffff   followsymbol:   20
Counter:2
data:ffffffee   followsymbol:   20
Counter:2
data:ffffffdd   followsymbol:    a
a nl symbol has been detected
Counter:65535