C: проблема Sscanf - PullRequest
       11

C: проблема Sscanf

1 голос
/ 28 июля 2010

У меня есть такой текстовый файл:

2
A 10 5
B 31 2
C 6 6

Я хочу прочитать номер первой строки в переменной
и прочитайте разделенный пробелами список каждой строки из 3 значений в 3 переменных. Я написал этот код:

iF=fopen(fileName,"r");
fgets(tmp,255,iF);
sscanf(tmp,"%d",&interval);

while(!feof(iF)){
    cur=(P *)malloc(sizeof(P));
    fgets(tmp,255,iF);
    sscanf(tmp,"%c %d %d",&Name,&AT,&ET);
    cur->jobName=Name;
    cur->arrivalTime=AT;
    cur->execTime=ET;
    add_to_list(head,cur);
}

Он работает правильно для строк 1,3,4, но не для строки 2! в строке 2 ничего не хранится! Когда я проверяю в Debugger, в файле есть странные символы (\ 342 \ 200 \ 252), и я не знаю, откуда они!

В чем проблема?

Спасибо

Ответы [ 4 ]

2 голосов
/ 28 июля 2010

Хмм ... Я ожидаю увидеть проблему с последней строкой, но случайно не вижу, почему у вас должна быть проблема в другом месте.OTOH, по крайней мере, когда я исправляю очевидную проблему с тем, как вы (пытаетесь) определить конец файла, мне кажется, что он работает нормально:

#include <stdio.h>
#include <stdlib.h>

typedef struct P { 
    char jobName;
    int arrivalTime;
    int execTime;
} P;

void show_P(P const *r) { 
    printf("Name: %c, Arrival Time: %d, Execute Time: %d\n", r->jobName, r->arrivalTime, r->execTime);
}

int main() {
    int interval;
    char Name;
    int AT, ET;
    char tmp[256];

    FILE *iF=fopen("stupid_input.txt","r");

    fgets(tmp,255,iF);
    sscanf(tmp,"%d",&interval);

    while(fgets(tmp, 255, iF)){
        P *cur=malloc(sizeof(P));
        sscanf(tmp,"%c %d %d",&Name,&AT,&ET);
        cur->jobName=Name;
        cur->arrivalTime=AT;
        cur->execTime=ET;
        show_P(cur);
    }
    return 0;
}

Результат:

Name: A, Arrival Time: 10, Execute Time: 5
Name: B, Arrival Time: 31, Execute Time: 2
Name: C, Arrival Time: 6, Execute Time: 6
2 голосов
/ 28 июля 2010

У меня работает следующий код:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    const char *fileName = "data.txt";
    FILE *iF;
    int interval;
    char Name[256], tmp[256];
    int AT, ET;

    iF = fopen(fileName, "r");
    if (fgets(tmp, 255, iF) == NULL)
        goto error;
    if (sscanf(tmp, "%d", &interval) != 1)
        goto error;

    while (fgets(tmp, 255, iF) != NULL) {
        if (sscanf(tmp, "%c %d %d", Name, &AT, &ET) != 3)
            goto error;
        fprintf(stdout, "%s, %d, %d\n", Name, AT, ET);
    }
    return 0;

error:
    fprintf(stderr, "error while reading from the file.\n");
    return 1;
}

Обратите внимание, какая часть кода предназначена для обработки ошибок.Это необходимо.

1 голос
/ 29 июля 2010

Символы (\ 342 \ 200 \ 252), которые вы видите, являются восьмеричными для 226, 128 и 170. Они не соответствуют символам, которые вы случайно набрали во входном файле.Я бы порекомендовал проверить ваш входной файл с помощью шестнадцатеричного редактора и посмотреть, нет ли там мусора.

Если нет, вы можете попробовать изменить способ чтения файла, чтобы увидеть, есть ли сбой в вашемкод, например, вы можете попробовать fscanf (что обычно не является предпочтительным):

FILE *iF = fopen("input.txt", "r");
if (fscanf(iF, "%d\n", &interval) != 1)
{
  fprintf(stderr, "Error parsing interval.\n");
  fclose(iF);
  return;
}

while (! feof(iF))
{
   cur = (P *)malloc(sizeof(P));
   if (fscanf(iF, "%c %d %u\n",&cur->jobName, &cur->arrivalTime, &cur->execTime) != 3)
   {
     fprintf(stderr, "Error parsing line.\n");
     free(cur);
     break;
   }
   add_to_list(head,cur);
}

Однако, поскольку другие опубликовали несколько методов, которые работают для них, а не для вас, входной файл, безусловно, является кандидатомошибка.

1 голос
/ 28 июля 2010

Чтобы устранить эту проблему, выполните несколько простых шагов отладки:

После того, как fgets в tmp, попробуйте распечатать его, чтобы увидеть, получилось ли то, что вы ожидаете.

Вы должны сохранить и отобразить возвращаемое значение sscanf, чтобы увидеть, если оно успешно.

...