简体   繁体   中英

C programing,reading integers from a file and over write them to letter

iv got an xls file to open in c. in this file there are 10 rows(each row represents a student), and in each row there are 12 numbers (each number represents the student grade for each subject,12 together). i need to scan the this data and calculate the GPA and the degree of classificaton for each students. so what i need to show on the screen is 12 grade (from number converted to letter) for each students(10) and their GPA and qualification classification. bellow is what i have done so far. im able to get the 10 rows onto a screen with 12 numbers in each row, but i dont know how i can make calculations with those numbers after i read them. thanks for any help or advice.

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

int main()  
{
    FILE * fPointer;
    fPointer=fopen("hello.xls", "r");

    int singleLine[150];

    while(!feof(fPointer)) {;
        fgets (singleLine,150,fPointer);
        puts(singleLine);
    }

    fclose(fPointer);

    return 0;
}

A few preliminary matters. The function signature for main() should be int main(void) , int main(int argc, char **argv) , or int main(int argc, char *argv[]) .

When you open a file, it is always necessary to check for failure. fopen() returns a null pointer when it fails, so you can check for this, and handle the error appropriately.

When reading the contents of a file in a loop, it is almost always a mistake to use feof() to control the loop. This is because feof() checks the end-of-file pointer, which is itself set only when an IO operation fails. In the case of the posted code, the loop is entered, and if there is nothing to read, the singleLine buffer contents remain unchanged, doubling the final line of the text file.

The simplest way to solve your problem is to take as given that each line contains 12 grades, and use sscanf() to parse each line of input as it is retrieved. This is not an elegant soulution:

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

#define MAX_STUDENTS  100

int main(void)
{
    /* Open a file */
    FILE *fPointer = fopen("hello.xls", "r");

    /* Make sure file opened successfully */
    if (fPointer == NULL) {
        fprintf(stderr, "Unable to open file\n");
        exit(EXIT_FAILURE);
    }

    char singleLine[500];
    double studentGPA[MAX_STUDENTS];
    int grade[12];
    size_t studentIndex = 0;

    /* Loop to fetch data and calculate GPAs */
    while ((fgets(singleLine, sizeof singleLine, fPointer)) != NULL &&
           studentIndex < MAX_STUDENTS) {
        if (sscanf(singleLine, "%d %d %d %d %d %d %d %d %d %d %d %d",
                   &grade[0], &grade[1], &grade[2], &grade[3],
                   &grade[4], &grade[5], &grade[6], &grade[7],
                   &grade[8], &grade[9], &grade[10], &grade[11]) != 12) {
            fprintf(stderr, "Incorrect number of grades on line %zu\n",
                    studentIndex);
            exit(EXIT_FAILURE);
        }
        int sum = 0;
        for (size_t i = 0; i < 12; i++) {
            sum += grade[i];
        }
        studentGPA[studentIndex] = sum / 12.0;
        ++studentIndex;
    }

    /* Display GPAs */
    for (size_t i = 0; i < studentIndex; i++) {
        printf("Student %zu GPA: %.2f\n", i, studentGPA[i]);
    }

    return 0;
}

Note that the return value of fgets() is checked to control the file read loop; when a null pointer is returned, or when the maximum number of students has been reached, the loop terminates. This code allows more than 10 students, but requires 12 grades per student. If a line of student grades does not contain 12 entries, the program prints an error message and exits. This is done by checking the return value from sscanf() , which is the number of successful conversions made. After each student's grades have been read, the average is calculated and stored in an array of studentGPA s.

I have assumed integer grade entries, as suggested in the question post, but the GPAs are calculated with floating point values. Also note that I have assumed that the grades are separated by whitespace. If the grades are separated by commas (or other delimiters) the format string will need to be modified accordingly.

A more elegant approach uses strtok() to break the lines of grades into individual tokens, based on a string of delimiters. These delimiters, delims = " ,\\r\\n" , indicate that strtok() should break the line into tokens where spaces, commas, or newlines occur. Other delimiters can simply be added to the string if needed.

Each line of grades is fetched, and strtok() is called a first time. If there is a token, it is converted to an int by atoi() , and added to sum . numGrades is updated, and strtok() is called again for a new token. When all grades have been read from a line, the average is calculated and stored in the studentGPA array. Note that the denominator in the average calculation is multiplied by 1.0 to force the calculation to be double . Also note that a more robust code would use strtol() instead of atoi() , checking the conversion for errors.

With this version, any number of students up to MAX_STUDENTS can be evaluated, with differing numbers of grades.

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

#define MAX_STUDENTS  100

int main(void)
{
    /* Open a file */
    FILE *fPointer = fopen("hello.xls", "r");

    /* Make sure file opened successfully */
    if (fPointer == NULL) {
        fprintf(stderr, "Unable to open file\n");
        exit(EXIT_FAILURE);
    }

    char singleLine[500];
    double studentGPA[MAX_STUDENTS];
    size_t studentIndex = 0;
    char *token;
    char *delims = " ,\r\n";

    /* Loop to fetch data and calculate GPAs */
    while ((fgets(singleLine, sizeof singleLine, fPointer)) != NULL &&
           studentIndex < MAX_STUDENTS) {
        int sum = 0;
        int numGrades = 0;

        /* Get grade tokens */
        token = strtok(singleLine, delims);

        while (token) {
            sum += atoi(token);
            ++numGrades;
            token = strtok(NULL, delims);
        }

        /* Calculate student GPA */
        studentGPA[studentIndex] = sum / (1.0 * numGrades);
        ++studentIndex;
    }

    /* Display GPAs */
    for (size_t i = 0; i < studentIndex; i++) {
        printf("Student %zu GPA: %.2f\n", i, studentGPA[i]);
    }

    return 0;
}

Here is a sample hello.xls file, with mixed comma and space delimiters. The first program will not work with this file, unless the commas are removed.

3 4 2 3 3 4 3 2 3 3 4 4
2 2 3 4 2 3 3 2 3 2 2 3
1 2 3, 3 2 3 3, 3, 4 2 3 3
3 2 2 3 3 2 1 2 2 2 1 1
4 4 3 4 4 4 4 3 4 4 4 4
4, 3, 4, 4, 4, 4, 4, 3, 4, 4, 4, 4
2 3 2 2 2 1 2 2 2 3 2 2
3 4 4 4 4 4 4 4 4 4 4 4
3 2 3 3 2 3 3 3 2 3 3 3
4 1 4 3 4 4 4 2 4 4 4 4

Here is the output of the second program with this grade file:

Student 0 GPA: 3.17
Student 1 GPA: 2.58
Student 2 GPA: 2.67
Student 3 GPA: 2.00
Student 4 GPA: 3.83
Student 5 GPA: 3.83
Student 6 GPA: 2.08
Student 7 GPA: 3.92
Student 8 GPA: 2.75
Student 9 GPA: 3.50

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM