确定课程平均成绩的程序

时间:2019-05-05 02:11:46

标签: c

该程序应该获取包含学生测验成绩的文本文件,并将其写入包含学生姓名的另一个文件中,并为学生分配成绩

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

void format(FILE *outputFile);
void copyNames(FILE *inputFile, FILE *outputFile);
void copyScores(FILE *inputFile, FILE *outputFile);

int main(int arc, char* argv[])
{
    FILE *inputScores, *averageScores;
    inputScores = fopen("quiz.txt", "r");
    averageScores = fopen("average.txt", "w");

    if (inputScores == NULL || averageScores == NULL)
    {
        printf("ERROR: The file(s) could not be opened!");
        return(1);
    }


    copyNames(inputScores, averageScores);
    copyScores(inputScores, averageScores);

    fclose(inputScores);
    fclose(averageScores);

    return 0;
}


void copyNames(FILE *inputFile, FILE *outputFile){
    char firstName[10], lastName[10], ch;
    ch = fgetc(inputFile); //sets ch to a place in the file
    fseek(inputFile, 0, SEEK_SET); //resets ch so it is at the beginning of the file
    while (ch != EOF){
        int i = 0, j = 0; //resets values in the array so you can overwrite it
        for (ch = fgetc(inputFile); ch != ' ' && ch != EOF; ch = fgetc(inputFile)){ //gets the first name and puts it into an array
            firstName[i] = ch;
            i++;
        }
        for (ch = fgetc(inputFile); ch != ' ' && ch != EOF; ch = fgetc(inputFile)){ //gets last name and puts it into array
            lastName[j] = ch;
            j++;
        }
        lastName[j] = '\0'; //truncates the arrays
        firstName[i] = '\0';
        while (ch != '\n' && ch != EOF){ //moves the placement of ch to avoid all the grades to get the next name
            ch = fgetc(inputFile);
        }
        fprintf(outputFile, "%s, %s \n", lastName, firstName); //prints the names to the output file
    }
}

void copyScores(FILE *inputFile, FILE *outputFile){
    fseek(inputFile, 0, SEEK_SET); //resets fgetc again
    char lineMemory[60], sc = fgetc(inputFile);
    while (sc != EOF){
        int i = 0, num = 0, scores[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        for (sc = fgetc(inputFile); sc != '\n' && sc != EOF; sc = fgetc(inputFile)){ //writes the whole line into an array
            lineMemory[i] = sc;
            i++;
        }
        lineMemory[i] = '\0'; //truncates the array
        for (int check = 0; lineMemory[check] != '\0'; check++){ //walks through the string
            if (isdigit(lineMemory[check]) != 0){ //looks for the digits in the string
                int j = lineMemory[check] - '0'; //turns the characters into integers
                scores[num] = j; //puts the integer into the array
                num++;
            }
        }
        float avg, total = 0;
        for (int indx = 0; indx < 10; indx++){
            total += scores[indx];
        }
        avg = total / 10; //finds average of the grades
        for (int x = 0; x < 10; x++){
            fprintf(outputFile, "%2d", scores[x]); //prints the quiz grades
        }
        fprintf(outputFile, "%10g\n", avg); //prints the average
    }
}

void copyAll(FILE *inputFile, FILE *outputFile){
    char ch = fgetc(inputFile);

    while (ch != EOF){
        ch = fgetc(inputFile);
        fputc(ch, outputFile);
    }
    printf("Data successfully written.\n");
}

结果应该是这样的:

 Alex Smith 98 100 90 82 92.5
 john Adams 100 90 82 90 90.5
 //92.5 and 90.5 being the average.

但是我的代码只显示了名称,并在名称下方显示了等级。喜欢:

 Alex Smith
 john adams
 98 100 90 
 100 90 82 etc...

1 个答案:

答案 0 :(得分:2)

您的代码中存在多个问题:

  • 您不能在2个单独的循环中处理名称和分数,因为预期的输出必须一次处理一行。
  • fgetc()返回一个int,请勿将其分配给char,否则您将无法可靠地检测到EOF
  • 您多次致电fgetc()。您应该结合使用阅读和测试习惯用语:

    void copyAll(FILE *inputFile, FILE *outputFile){
        int ch ;
    
        while ((ch = fgetc(inputFile)) != EOF) {
            fputc(ch, outputFile);
        }
        printf("Data successfully written.\n");
    }
    
  • 您永远不会检查潜在的缓冲区溢出:无效的输入将导致未定义的行为。

  • copyScores中将分数转换为数字的代码是错误的:它只能处理一位数的分数。
  • 您用"%2d"输出分数,不会将大于9的分数分开。请改用" %d"
  • 您阅读了num分,但始终输出10分及其平均值。
  • 呼叫fseek(inputFile, 0, SEEK_SET);毫无用处。只有在更新模式下打开的流才需要使用它们,要正确使用它们非常棘手。

这是一个简单得多的版本:

#include <stdio.h>

int main(int argc, char *argv[]) {
    FILE *input, *output;
    char firstname[50], lastname[50];
    int score, n, total;

    input = fopen("quiz.txt", "r");
    output = fopen("average.txt", "w");
    if (input == NULL || output == NULL) {
        printf("ERROR: The file(s) could not be opened!");
        return 1;
    }

    while (fscanf(input, "%49s%49s", firstname, lastname) == 2) {
        fprintf(output, "%s %s", firstname, lastname);
        for (n = 0, total = 0; fscanf(input, "%d", &score) == 1; n++) {
            fprintf(output, " %d", score);
            total += score;
        }
        fprintf(output, " %.2f\n", n == 0 ? 0.0 : (double)total / n);
    }
    fclose(input);
    fclose(output);

    return 0;
}