C编程,从文件中读取整数并将其写入字母

时间:2017-03-22 23:33:28

标签: c arrays file for-loop fgets

iv在c中打开了一个xls文件。在这个文件中有10行(每行代表一个学生),每行有12个数字(每个数字代表每个主题的学生成绩,12个在一起)。我需要扫描这些数据并计算每个学生的GPA和分类程度。所以我需要在屏幕上显示的是每个学生(10)的12年级(从数字转换为字母)以及他们的GPA和资格分类。吼叫是我到目前为止所做的。我能够将10行放到屏幕上,每行有12个数字,但我不知道在阅读之后我怎么能用这些数字进行计算。感谢您的帮助或建议。

#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;
}

1 个答案:

答案 0 :(得分:0)

一些初步事项。 main()的功能签名应为int main(void)int main(int argc, char **argv)int main(int argc, char *argv[])

打开文件时,始终需要检查是否有失败。 fopen()在失败时返回空指针,因此您可以检查这一点,并适当地处理错误。

在循环中读取文件的内容时,使用feof()来控制循环几乎总是错误的。这是因为feof()检查文件结束指针,该指针仅在IO操作失败时自行设置。对于发布的代码,输入循环,如果没有要读取的内容,singleLine缓冲区内容保持不变,将文本文件的最后一行加倍。

解决问题的最简单方法是假设每行包含12个等级,并使用sscanf()在检索时解析每行输入。这不是一个优雅的解决方案:

#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;
}

请注意,检查fgets()的返回值以控制文件读取循环;当返回空指针时,或者当达到最大学生数时,循环终止。此代码允许10名以上的学生,但每名学生需要12个年级。如果一行学生成绩不包含12个条目,程序将打印一条错误消息并退出。这是通过检查sscanf()的返回值来完成的,这是成功转换的次数。读完每个学生的成绩后,计算平均值并将其存储在studentGPA s的数组中。

我假设整数等级条目,如问题帖子中所建议的那样,但GPA是使用浮点值计算的。另请注意,我假设等级由空格分隔。如果等级用逗号(或其他分隔符)分隔,则需要相应地修改格式字符串。

更优雅的方法是使用strtok()根据一系列分隔符将等级分为单个标记。这些分隔符delims = " ,\r\n"表示strtok()应该将行划分为出现空格,逗号或换行符的标记。如果需要,可以简单地将其他分隔符添加到字符串中。

获取每个成绩系列,并且第一次调用strtok()。如果有令牌,则会int将其转换为atoi(),并添加到sumnumGrades已更新,并再次调用strtok()以获取新令牌。从一行读取所有等级后,计算平均值并将其存储在studentGPA数组中。请注意,平均计算中的分母乘以1.0以强制计算为double。另请注意,更强大的代码将使用strtol()而不是atoi(),检查转换是否存在错误。

使用此版本,可以评估任何数量最多MAX_STUDENTS的学生,并且评分等级不同。

#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;
}

这是一个示例hello.xls文件,带有混合逗号和空格分隔符。除非删除逗号,否则第一个程序将无法使用此文件。

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

以下是使用此成绩档案的第二个程序的输出:

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