0

I have this gradebook program I am writing and I have an infinite loop occurring at the very end of my get_data function I cannot figure out why it is not exiting the loop. Here is a sample of what I am supposed to run:

ID, NAME, GRADE
2442
Kapowski, Kelly
87 99 100 87 88 -99
1254
Slater, A.C.
90 100 -99
8742
Morris, Zack
77 65 50 80 66 -99

The code:

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

#define MAX_NAME 50
#define MAX_SCORES 20
#define MAX_FILE_NAME 100

typedef struct {
    char name[MAX_NAME];
    int id;
    double scores[MAX_SCORES];
    int num_scores;

} student_t;

double student_average (student_t student);
FILE * get_data_file();
void get_data(student_t students[], int num_students, FILE *input_file);
void sort_student_array(student_t students[], int num_students);
int find_index_of_next(const student_t students[], int num_elements, int start_index);
void display_data(const student_t students[], int num_elements);

int main()
{
    student_t *students;
    FILE *input_file;
    int num_students;


    input_file = get_data_file();

    fscanf (input_file, "%d", &num_students);

    students = (student_t *)calloc(num_students, sizeof(student_t));

    get_data(students, num_students, input_file);

    sort_student_array(students, num_students);

    display_data(students, num_students);

    free(students);

    return 0;
}

double student_average (student_t student)
{
    double average,
           total;
    int count;

    for (count = 0; count < student.num_scores; count++)
        total += student.scores[count];

    average = total / student.num_scores;

    return average;
}

FILE * get_data_file()
{
    int valid = 0;
    char file_name[MAX_FILE_NAME];
    FILE *in_file;

    printf("Welcome to the automated grade book program. Version 2.0\n");

    do
    {

        printf ("Enter student data filename:");
        scanf ("%s", file_name);
        in_file = fopen (file_name, "r");

        if (in_file != NULL)
        {
            valid = 1;
        }
        else
        {
            printf ("Unable to open file %s. Try again.\n", file_name);
        }
    } while (!valid);
    return in_file;
}

void get_data(student_t students[],
              int num_students,
              FILE *input_file)
{
    int count;
    int count2;
    student_t student;
    double value;

    for (count = 0; count < num_students; count++)
    {

        fscanf (input_file, "%d\n", &student.id);

        fgets (student.name, MAX_NAME, input_file);

        student.name[strlen(student.name)-1] = '\0';

        fscanf(input_file, "%lf", &value);

/*
/I am getting stuck right HERE
*/
        count2 = 0;
        while (value != -99)
        {
            student.scores[count2] = value;
            fscanf(input_file, "%lf", &value);
            count2++;             
        }

        student.num_scores = count2;

        students[count] = student;

    }
}
Zong
  • 6,160
  • 5
  • 32
  • 46
  • 1
    I have a strong feeling value is never set to -99. Check=> `while (value != -99)` – Bitmap Dec 04 '13 at 19:41
  • 1
    Always check return value of any *scanf* family function, in case there is a parse error (so the value you are reading to is left unmodified). – hyde Dec 04 '13 at 19:44
  • A debugger would be your true friend. You already know where to set the breakpoint. – devnull Dec 04 '13 at 19:47
  • I've an even stronger feeling that direct floating-point equality comparison is a generally bad idea. You may wish to debug-print the values you're retrieving just to validate you're getting what you think you are. – WhozCraig Dec 04 '13 at 19:47
  • +1 for [Saved by the Bell](http://en.wikipedia.org/wiki/Saved_by_the_Bell) names – Kninnug Dec 04 '13 at 19:49

1 Answers1

2

I am going to bet that one of the - signs in your file is actually a different character. This causes fscanf to fail, value is never set, and you have an infinite loop. You should check the return value of the conversion function- eg

if(fscanf(input_file, "%lf", &value) !=1) break;

It would not be the first assignment with a tricky twist in it...

Floris
  • 45,857
  • 6
  • 70
  • 122
  • You could do a hex dump of your input file to see if I am right... Or do `grep "-99" | wc -l` and see if you get as many matches as you expect... – Floris Dec 04 '13 at 20:50
  • 1
    Agree to both your points on my _deleted_ answer. +1 to yours – ryyker Dec 04 '13 at 20:53
  • I just realized that I am really just expanding on @hyde's comment - so here's a tip of the hat to you! – Floris Dec 04 '13 at 20:53
  • See [this recent question](http://stackoverflow.com/questions/20316580/fscanf-stucks-in-an-infinite-loop/20316733#20316733) for example of "tricky character to cause fscanf failure" – Floris Dec 04 '13 at 20:56
  • I am now beginning to doubt my solution, since the [original assignment](http://uenics.evansville.edu/~hwang/f12-courses/cs210/prog8.html) states _The file is always well-formed. That is, there always is three lines of data for each student and the third line always ends with -99._ – Floris Dec 05 '13 at 13:18