使用带有C的fscanf检测0x0a

时间:2011-05-30 01:06:16

标签: c scanf

我正在阅读如下文件:

  

31 0A 34 0A 31 0A 38 0A 34 0A 33 0A 36   0A 31 0A 31 0A 39 0A 31 30 0A 31 30 0A   35 0A 35 0A 31 30 0A 31 0A 33 0A 36 0A   33 0A 31 30 0A 35 0A 31 0A 31 30 0A 39   0A 35 0A 38 0A 33 0A 36 0A 34 0A 33 0A   36 0A 35 0A 31 30 0A 37 0A 32 0A 36 0A   33 0A 36 0A 35 0A 31 30 0A 37 0A 39 0A   33 0A 36 0A 32 0A 36 0A 35 0A 34 0A   0A 30 20 31 20 34 37 32 37 0A 30 20   33 20 36 33 36 33 0A 30 20 34 20 33 36   35 37 0A 30 20 35 20 33 31 33 30 0A 30   20 36 20 32 34 31 34 0A 30

我打算用以下代码阅读文件的第一部分,直到找到序列0A 0A:

readed = fscanf(f,"%s", str_aux); 

在0A 0A之后,我需要阅读以下句子:

readed = fscanf(f,"%s %s %s", str_aux1, str_aux3, str_aux3);

如何检测0A 0A以便开始读取文件的第二部分。

我想使用以下结构:

while (something){

   readed = fscanf(f,"%s", str_aux);
}

while (fscanf(f, "%s %s %s", a,b,c)!= EOF){

...
...
}

某些条件的想法(在第一次内部)?

我正在使用Linux。

3 个答案:

答案 0 :(得分:1)

我可能会使用fgetc和状态引擎。类似的东西:

int state=0;
char d;
while ((d = fgetc(f)) >= 0) {
  if (d==0x0a)
   state++;
  else
   state = 0;
  if (state == 2)
   do_something();
}
但是,我可能会使用fgets。类似的东西:

int state=0;
char line[MAXLINE];
while (fgets(line,sizeof(line),f))
  if (state == 0 && *line == 0x0a)
    state=1;
  else if (state == 1)
  {
    sscanf(line,"%s %s %s",a,b,c);
    do_something_else();
  }
}

一般来说,我对调用fscanf()非常谨慎。我总是发现fscanf解析器非常脆弱。我更有可能通过fgets或其他东西获得该行,然后解析结果。

答案 1 :(得分:0)

如果您坚持使用fscanf,则可以一次读取一个字符。例如,


int nl_count = 0;
char current;
while(nl_count < 2)
{
    readed = fscanf(f,"%c",¤t);
    /* check that readed == 1, throw error otherwise */
    if(current == 0x0A)
        nl_count++;
    else
        nl_count = 0;
}

我认为这将完全符合您的要求。它一次读取一个字符,直到出现两个连续的0x0A(换行符)。然后循环中断,你可以继续循环第二个循环。

我同意Seth的观点,fgets或fgetc更适合第一个循环。

答案 2 :(得分:0)

当您查看问题的来源时,大多数行上有13个十六进制数字,这是一个不寻常的数字可供选择。因此,我们可以简单地假设输入是一个以空格分隔的十六进制数字序列。

因此,我(对于一些评论员)使用gethex()函数来阅读下一个信息似乎是合乎逻辑的。

int gethex(void)
{
    int x;
    if (scanf("%2x", &x) != 1)
        x = -1;
    return x;
}

然后可以用它来读取字符:

int oc = 0;
int c;

while ((c = gethex()) != -1)
{
    if (oc != 0x0A || c != 0x0A)
    {
        oc = c;
        continue;
    }
    /* Read to 0x0A in a row - proceed as required */
    int a, b, c;
    if ((a = gethex()) == -1 ||
        (b = gethex()) == -1 ||
        (c = gethex()) == -1)
        ...error - unexpected EOF (or other format error)...
    ... Process a, b, c ...
}

请注意,如果数据中存在错误,则会停止此设置 - 十六进制或空格以外的字符。