Обнаружение 0x0a с помощью fscanf с C - PullRequest
2 голосов
/ 30 мая 2011

Я читаю файл как:

31 0A 34 0A 31 0A 38 0A 34 0A 33 0A 36 0А 31 0А 31 0А 39 0А 31 30 0А 31 30 0А 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 0А 35 0А 38 0А 33 0А 36 0А 34 0А 33 0А 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 ]

1 голос
/ 30 мая 2011

Я мог бы использовать 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 или чего-то еще, а затем проанализировал результат.

0 голосов
/ 30 мая 2011

Когда вы смотрите на источник вопроса, в большинстве строк есть 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 ...
}

Обратите внимание, что это останавливается, если в данных есть ошибка - aсимвол, отличный от шестнадцатеричного или пробела.

0 голосов
/ 30 мая 2011

Если вы настаиваете на использовании fscanf, вы можете читать по одному символу за раз.Например,


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

Я думаю, что это будет именно то, что вы хотите.Это читает по одному символу за раз, пока не появятся два последовательных 0x0A (новые строки).Затем цикл прерывается, и вы можете перейти ко второму циклу while.

Я согласен с Сетом, однако, что fgets или fgetc будут более подходящими для первого цикла.

...