2014-11-19 4 views
1

В основном мне нужно отсканировать все значения из этого файла ... которые он в значительной степени делает, но, похоже, пропускает случайные, поэтому он не выравнивается правильно. (Это только часть того, что мне нужно сделать для задания, поэтому вы не «раздаете ответ», и я все еще хочу разобраться в этом самостоятельно, просто нужно немного помочь понять это, потому что я довольно застрял)Почему мой fscanf продолжает пропускать случайные числа?

https://www.dropbox.com/sh/wterbuyxm76wwrz/AADEtolX68OFrKELI_lxT8_Ra/assignments%20and%20labs/labs/lab5_inputFile.txt?dl=0

Вот код:

int main() 
{ 
    FILE *fp; 
    char x[15]; 
    float ID [1000]; 
    int i=0, j=0; 
    float homework [1000]; 
    float lab [1000]; 
    float midterm [1000]; 
    float Final [1000]; 
    int count=0; 
    char headers[35]; 
    char y; 

    fp= fopen("lab5_inputFile.txt", "r"); 

    while (fscanf(fp, "%s", x)!=EOF){ 
     if (count > 728){ 
      fscanf(fp, "%f", &ID[i]); 
      printf("ID : %.1f\n", ID[i]); 
      fscanf(fp, "%f", &homework[i]); 
      printf("Homework: %.1f\n", homework[i]); 
      fscanf(fp, "%f", &lab[i]); 
      printf("lab: %.1f\n", lab[i]); 
      fscanf(fp, "%f", &midterm[i]); 
      printf("Midterm: %.1f\n", midterm[i]); 
      fscanf(fp, "%f", &Final[i]); 
      printf("Final: %.1f\n", Final[i]); 

      i++; 
     } 
      count ++; 

    } 
    printf("count = %d\n", count); 
    fclose(fp); 

я только просмотрел последние несколько значений, чтобы сделать его более удобным для чтения/отладки в реальном коде будет пропускать только также есть много других вещей, которые я планирую изменить перед отправкой, например, я мог бы использовать тип указателя и malloc вместо массивов и кучу другие вещи, но мой главный вопрос заключается в том, как исправить проблему, которую я испытываю при чтении из файла в массивы.

Заранее благодарен!

+2

@Mohit Jain "fscanf возвращает число прочитанных символов" неверна. 'fscanf()' возвращает количество преобразованных полей или 'EOF'. – chux

+0

Примите во внимание чтение документации по каждой функции, которую вы используете (например, [fscanf (3)] (http://man7.org/linux/man-pages/man3/scanf.3.html) ...). Скомпилируйте все предупреждения и информацию об отладке ('gcc -Wall -Wextra -g'). ** Используйте отладчик ** ('gdb'). Вы могли бы найти свою проблему, не спрашивая! –

+0

Почему код игнорирует результаты первых 728 вызовов fscanf()? – user3629249

ответ

0

Вы пропускаете первую строку x каждый раз. Вы должны переписать как:

char x[100]; 
/* while (fscanf(fp, "%s", x)!=EOF){ */ 
fgets(x, 100, fp); /* Skip first line */ 
for(; /* ever */;) { 
    if(5 == fscanf(fp, "%f%f%f%f%f", &ID[i], &homework[i], &lab[i], &midterm[i], &Final[i])) { 
     printf("ID : %.1f\n", ID[i]); 
     printf("Homework: %.1f\n", homework[i]); 
     printf("lab: %.1f\n", lab[i]); 
     printf("Midterm: %.1f\n", midterm[i]); 
     printf("Final: %.1f\n", Final[i]); 
     i++; 
    } else break; 
} 
повторил подход

Live example here

+0

'feof (fp)' не в правильном подходе. Текстовый файл OP заканчивается символом '' \ n'', и ваш ответ рассчитывается на файл, заканчивающийся номером. Когда файл заканчивается чем-то другим, чем число, последний 'fscanf («% f », & Final [i]);' не устанавливает EOF и появляется дополнительный набор из 5 'fscanf()'. Попробуйте свое решение с текстовым файлом, заканчивающимся на '' \ n'', чтобы это увидеть. Вместо 'if (feof (fp))', проверьте результат каждого 'fscanf()', особенно последнего. – chux

+0

@chux Я пытаюсь прочитать все значения. Если файл не читает 'eof' даже после прочтения всего, я увеличиваю' i', объявляя, что чтение было успешным. В противном случае я сломаю объявление, по крайней мере, на 'fscanf', не увенчалось успехом. (Хотя отладочные отпечатки OP будут казаться нежелательными) –

+0

Похоже, вы не пытались запустить код на предлагаемом входе. Если последний номер успешно прочитал пробел после него, 'feof()' не будет истинным, а затем следующий набор из 5 'fscanf (fp,"% f ", ...' будет терпеть неудачу. не проверять результаты 'fscanf()', этот сбой не обнаружен.После этих сбоев функция feof() 'будет тогда истинна. Чтобы быть понятным' feof() 'does _not_ сообщит, что больше данных не будет доступно, 'feof()' сообщает, что операция _previous_ IO показала, что больше нет данных. – chux

0

OP читает «группа небелого пространства текста, а затем 5 чисел». Код должен читать строку один раз, бросить его и , затем повторяющихся групп из 5 чисел.

Прочитать и бросить первую строчку, затем прочесть строки до EOF, используя fgets(). Сканирование буфера с помощью sscanf() или strtod().

char buf[100]; 
fgets(buf, sizeof buf, fp); // Read and toss first line 
i = 0; 

while (fgets(buf, sizeof buf, fp) != NULL) { // Read until EOF 
    if ((i >= 1000) || (sscanf(buf, "%f%f%f%f%f", &ID[i], &homework[i], &lab[i], 
     &midterm[i], &Final[i]) != 5)) { 
    fputs("Quit as too many lines or ill formatted\n", stderr); 
    break; 
    } 
    printf("ID : %.1f\n", ID[i]); 
    printf("Homework: %.1f\n", homework[i]); 
    printf("lab: %.1f\n", lab[i]); 
    printf("Midterm: %.1f\n", midterm[i]); 
    printf("Final: %.1f\n", Final[i]); 
    i++; 
} 
0
#include <stdio.h> 
#include <stdlib.h> 

struct grade 
{ 
    float ID; 
    float homework; 
    float lab; 
    float midterm; 
    float final; 
}; 

#define ARRAYSIZE (1000) 

int main() 
{ 
    FILE *fp; 
    struct grade studentGrades[ARRAYSIZE] = {{0},{0},{0},{0},{0}}; 
    int i=0; 
    int count=0; 


    if(NULL == (fp= fopen("lab5_inputFile.txt", "r"))) 
    { 
     perror("fopen for read of lab5_inputFile.txt"); 
     exit(1); 
    } 

    // implied else fopen successful 

    char* dummy = malloc(1000*sizeof(char)); 
    if(NULL == dummy) 
    { 
     perror("malloc for dummy buffer"); 
     exit(2); 
    } 

    // implied else, malloc successful 

    char * firstLine = fgets(dummy, sizeof(dummy), fp); // step past first line of file 
    if(NULL == firstLine) 
    { 
     perror("fget of first line of file"); 
     exit(3); 
    } 

    // implied else, fgets successful 

    free(dummy); 

    int itemCount = 0; 
    for (i = 0; i < ARRAYSIZE; i++) 
    { 
     itemCount = fscanf(fp, " %f", &studentGrades[i].ID); 
     if(EOF == itemCount) // Note:making assumption that every line, 
           // after first, is properly formatted 
     { 
      break; // exit for loop 
     } 
     if(1 != itemCount) 
     { 
      perror("fscanf"); 
      exit(4); 
     } 

     // implied else read of ID successful, not end of file 

     printf("ID : %.1f\n", studentGrades[i].ID); 

     if(1 != fscanf(fp, " %f", &studentGrades[i].homework)) 
     { 
      perror("fscanf of homework"); 
      exit(5); 
     } 

     // implied else, read of homework successful 

     printf("Homework: %.1f\n", studentGrades[i].homework); 

     if(1 != fscanf(fp, " %f", &studentGrades[i].lab)) 
     { 
      perror("fscanf of lab"); 
      exit(6); 
     } 

     // implied else, read of lab successful 

     printf("lab: %.1f\n", studentGrades[i].lab); 

     if(1 != fscanf(fp, " %f", &studentGrades[i].midterm)) 
     { 
      perror("fscanf of midterm"); 
      exit(7); 
     } 

     // implied else, read of midterm successful 

     printf("Midterm: %.1f\n", studentGrades[i].midterm); 

     if(1 != fscanf(fp, " %f", &studentGrades[i].final)) 
     { 
      perror("fscanf of final"); 
      exit(8); 
     } 

     // implied else, read of final successful 

     printf("Final: %.1f\n", studentGrades[i].final); 

     count ++; 

    } // end for 

    printf("count = %d\n", count); 
    fclose(fp); 

    return(0); 
} 
+0

'fgets (dummy, sizeof (dummy), fp)' не будет работать по желанию. 'sizeof (dummy)' - размер указателя, вероятно, 4 или 8. Предложите # #define N 1000 ... fgets (dummy, N, fp) '. – chux

+0

Примечание: пространство в формате 'fscanf (fp,"% f ", ...' не требуется. OTOH тоже не является проблемой. – chux

+0

Интересно, что этот код использует локальный массив для 'studentGrades' и выделенный массив для 'dummy'. Приятно показать разнообразие определений больших массивов, иначе неясно, почему два разных подхода. – chux

Смежные вопросы