Как сделать условный разбор с помощью fscanf? - PullRequest
4 голосов
/ 18 августа 2010

У меня есть несколько строк, которые я хочу проанализировать из текстового файла.Некоторые строки начинаются с x и продолжаются несколькими y:z, а другие полностью состоят из нескольких y:z с, где x,y,z - числа.Я попробовал следующий код, но он не работает.Первая строка также читается в y в y:z.

...
if (fscanf(stream,"%d ",&x))
if else (fscanf(stream,"%d:%g",&y,&z))
...

Есть ли способ заставить scanf читать символ только в том случае, если за ним следует пробел?

Ответы [ 3 ]

3 голосов
/ 18 августа 2010

Семейство функций *scanf не позволяет вам делать это изначально. Конечно, вы можете обойти эту проблему, считав минимальное количество элементов, которые, как вы знаете, будут присутствовать в каждой строке ввода, подтвердите возвращаемое значение *scanf и затем продолжайте постепенно, по одному элементу за раз, каждый раз проверяя возврат значение для успеха / неудачи.

if (1 == fscanf(stream, "%d", &x) && (x == 'desired_value)) {
    /* we need to read in some more : separated numbers */
    while (2 == fscanf(stream, "%d:%d", &y, &z)) { /* loop till we fail */
          printf("read: %d %d\n", y, z); 
    } /* note we do not handle the case where only one of y and z is present */
} 

Лучше всего справиться с этим, прочитав строку, используя fgets, а затем проанализируйте строку самостоятельно, используя sscanf.

if (NULL != fgets(stream, line, MAX_BUF_LEN)) { /* read line */
   int nitems = tokenize(buf, tokens); /* parse */
}

...
size_t tokenize(const char *buf, char **tokens) {
    size_t idx = 0;
      while (buf[ idx ] != '\0') {
          /* parse an int */
          ...
      }
}
1 голос
/ 18 августа 2010
char line[MAXLEN];

while( fgets(line,MAXLEN,stream) )
{
  char *endptr;
  strtol(line,&endptr,10);
  if( *endptr==':' )
    printf("only y:z <%s>",line);
  else
    printf("beginning x <%s>",line);
}
0 голосов
/ 19 августа 2010

Я нашел грубый способ сделать то, что хотел, без необходимости переключаться на fgets (что, вероятно, было бы безопаснее в долгосрочной перспективе).

if (fscanf(stream,"%d ",&x)){...}
else if (fscanf(stream,"%d:%g",&y,&z)){...}
else if (fscanf(stream,":%g",&z)){
    y=x;
    x=0;
}
...