[英]making program read certain parts of the file
我有一个包含学生姓名和成绩的文件,并且我想编写一个程序,该程序可以根据用户选择对他们的成绩进行排序(如期中1,期中2)。 我写了关于选择部分并打开文件的内容,但我不知道如何使程序仅读取文件的某些部分(例如,仅中期1年级)并仅对它们进行排序。 到目前为止,这是我写的内容。
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int number;
char name[30];
char surname[30];
int midterm1,midterm2,midterm3;
} Student;
int main()
{
int choice,studentnumber,midterm1,midterm2,midterm3;
char surname;
FILE *cfPtr;
struct student *name;
name = malloc( 10 * sizeof(Student));
if ((cfPtr = fopen("grades.txt", "r")) == NULL)
printf("File cannot be opened.\n");
else {
const int STUDENTSMAX = 100;
Student students[STUDENTSMAX];
int i = 0;
while (!feof(cfPtr))
{
fscanf(cfPtr, "%d%s%s%d%d%d", &students[i].number, &students[i].name,&students[i].surname, &students[i].midterm1, &students[i].midterm2, &students[i].midterm3);
printf("%4d%15s%15s%10d%10d%10d\n", students[i].number, students[i].name,students[i].surname, students[i].midterm1, students[i].midterm2, students[i].midterm3);
i++;
}
printf("What would you like to do? \n"
"1- Sort according to midterm 1\n"
"2- Sort according to midterm 2\n"
"3- Sort according to midterm 3\n"
"4- Exit\n");
scanf("%d",&choice);
while (choice != 4);{
switch (choice) {
case 1:
qsort(students,10,sizeof(int),comp);
for (i=0; i<9; i++)
printf("%4d%15s%15s%10d%10d%10d\n", students[i].number, students[i].name,students[i].surname, students[i].midterm1);
fclose(cfPtr);
}
system("PAUSE");
return 0;
}
鉴于可能是某种形式的自由文本文件(基于显示的代码),仅读取整个文件(就像您已经在做的那样)并且仅使用所需的部分可能是有意义的。 如果文本文件具有固定偏移量的非常特定的格式,则可以查找文件中的某些位置并读取特定的列值,然后查找下一个偏移量并从下一行读取列值。 但这可能是麻烦多于其应有的价值,并且效率不会更高(如果有的话)。
话虽如此,为了对结果进行排序,您可能仍然需要整个文件。 例如,如果您仅读取“期中1”值并对其进行排序,则结果将仅按成绩进行排序,而无需任何关联的名称和学生编号。 因此,没有更多地了解目标,则可以考虑创建一个struct
,可容纳单行(学号,姓名,midterm1等)。 然后创建一个数组,并将每一行读入数组的元素。 如果知道前面有多少行,则可以将数组分配为一个块,否则在增长数组时可能需要重新分配它。
阅读完整个数组后,您可以根据所需的值进行排序(例如,使用qsort
。
提到了这一点,现有显示的代码存在一些问题/问题:
printf
吗? while
循环在其结束括号后有一个多余的分号(;),这意味着它的主体为空,而不是表面上预期的printf
和switch
语句。 switch
语句有点奇怪。 我认为这是“未完成”的部分。 但是将fclose
包括在内似乎很奇怪。 它可能应该在else
主体的末尾。 system("PAUSE");
也许不是最佳选择。 也许使用getch
暂停输入会更有意义。 编辑这里是一些其他信息,以回应您的评论,要求提供更多详细信息。 在我看来,这听起来像是功课,因此仅给出答案似乎并不正确。 但这是一种方法:
struct
(基本上放入您当前已定义为局部变量的6个变量中)。 grades
)作为您定义的结构的pointer
。 malloc
分配内存并将其分配给刚刚提到的指针。 内存量可能是整个过程中最棘手的部分。 malloc
的size参数类似于numRecs * sizeof( yourstruct )
。 问题是numRecs
应该是什么。 如果这是一项任务,并且您被告知会有多少条记录(最多),那么就使用它。 但是,如果它是“未知的”,则有两种处理方法。 一种是猜测一个数字(例如100),然后在循环中读取它们(如果您超过100,则使用realloc
。另一种选择(可能效率较低)将使用两个循环-一次读取它们而不存储它们但只需计算它们,然后分配已知大小并再次读取即可。 我会使用realloc版本。 malloc
)。 例如,而不是studentnumber
你会用grades[arraypos].studentnumber
。 当您阅读它们时,请记下它们的数量。 然后,您可以使用qsort
对数组进行排序。 编辑2
FILE *cfPtr;
成员不应该在其中。 它仍然应该是局部变量。 typedef struct { ... } Student;
。 这样,您可以只在代码中使用Student
而不是struct Student
。 请注意,我将名称大写(命名时出于个人喜好,使其看起来不像变量名)。 name = malloc( 50 * sizeof( struct student ));
: name = malloc( 50 * sizeof( struct student ));
(或malloc( 50 * sizeof( Student ));
如果将其更改为使用typedef,则假定从文件中读取的记录不超过50条。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.