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;
}
答案 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()
,并添加到sum
。 numGrades
已更新,并再次调用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