[英]making program read certain parts of the file
I've a file which contains names and grades of students, and I'd like to write a program which can sort their grades (like midterm 1,midterm 2) according to user choice. 我有一个包含学生姓名和成绩的文件,并且我想编写一个程序,该程序可以根据用户选择对他们的成绩进行排序(如期中1,期中2)。 I wrote as far as the choice part and opening the file, yet I don't know how to make program read only certain part of the file (like only Midterm 1 grades for example) and sort them only.
我写了关于选择部分并打开文件的内容,但我不知道如何使程序仅读取文件的某些部分(例如,仅中期1年级)并仅对它们进行排序。 Here's what I've wrote so far;
到目前为止,这是我写的内容。
#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;
}
Given what might be a somewhat free form text file (based on the shown code), it probably makes sense just to read the entire file (somewhat like you are already doing) and only use the parts that you need. 鉴于可能是某种形式的自由文本文件(基于显示的代码),仅读取整个文件(就像您已经在做的那样)并且仅使用所需的部分可能是有意义的。 If the text file has a very specific format with fixed offsets, you could seek to certain locations in the file and read a specific column value, then seek to the next offset and read the column value from the next row.
如果文本文件具有固定偏移量的非常特定的格式,则可以查找文件中的某些位置并读取特定的列值,然后查找下一个偏移量并从下一行读取列值。 But that is probably more trouble than it is worth and would not be much more efficient (if at all).
但这可能是麻烦多于其应有的价值,并且效率不会更高(如果有的话)。
Having said that, to sort the results, you probably need the entire file anyway. 话虽如此,为了对结果进行排序,您可能仍然需要整个文件。 For example, if you just read and sort the "midterm 1" value, then the result would just be sorted grades without any associated name and student number.
例如,如果您仅读取“期中1”值并对其进行排序,则结果将仅按成绩进行排序,而无需任何关联的名称和学生编号。 So without knowing more about the goal, you might consider creating a
struct
that can hold a single row (student number, name, surname, midterm1, etc.). 因此,没有更多地了解目标,则可以考虑创建一个
struct
,可容纳单行(学号,姓名,midterm1等)。 Then create an array of those and read each row into an element of the array. 然后创建一个数组,并将每一行读入数组的元素。 If you know how many rows exist up front, you can allocate the array in one chunk, otherwise you might need to reallocate it as you go to grow it.
如果知道前面有多少行,则可以将数组分配为一个块,否则在增长数组时可能需要重新分配它。
Once you have read the entire array, you could sort based on the desired value (eg, with qsort
. 阅读完整个数组后,您可以根据所需的值进行排序(例如,使用
qsort
。
Having mentioned that, there a few problems/issues with the existing shown code: 提到了这一点,现有显示的代码存在一些问题/问题:
printf
? printf
吗? while
loop has an extraneous semicolon (;) following its closing paren, which means that it has an empty body rather than the apparently intended printf
and switch
statement. while
循环在其结束括号后有一个多余的分号(;),这意味着它的主体为空,而不是表面上预期的printf
和switch
语句。 switch
statement is a bit odd as written. switch
语句有点奇怪。 I assume that is the "unfinished" part. fclose
in it seems strange. fclose
包括在内似乎很奇怪。 It should probably be at the end of the main else
. else
主体的末尾。 system("PAUSE");
system("PAUSE");
is maybe not the best choice. getch
would make more sense to pause for input. getch
暂停输入会更有意义。 Edit Here is some additional information in response to your comment asking for more details. 编辑这里是一些其他信息,以回应您的评论,要求提供更多详细信息。 This sounds like homework to me, so it doesn't seem right just to give the answer.
在我看来,这听起来像是功课,因此仅给出答案似乎并不正确。 But here is one way to do it:
但这是一种方法:
struct
with the 6 items that are in the file (basically put in the 6 variables that you currently have defined as local variables). struct
(基本上放入您当前已定义为局部变量的6个变量中)。 grades
) as a pointer
to struct that you defined. grades
)作为您定义的结构的pointer
。 malloc
to allocate memory and assign it to the pointer just mentioned. malloc
分配内存并将其分配给刚刚提到的指针。 The amount of memory is perhaps the trickiest part of this whole thing. malloc
will be something like numRecs * sizeof( yourstruct )
. malloc
的size参数类似于numRecs * sizeof( yourstruct )
。 The question is what numRecs
should be. numRecs
应该是什么。 If this is an assignment and you were told how many records there would be (a maximum), then just use that. realloc
if you exceed 100. The other alternative (probably less efficient) would be to use two loops - read through them once without storing them but just count them and then allocate the known size and read them again. realloc
。另一种选择(可能效率较低)将使用两个循环-一次读取它们而不存储它们但只需计算它们,然后分配已知大小并再次读取即可。 I would use the realloc version. malloc
ed). malloc
)。 For example, instead of studentnumber
you would use grades[arraypos].studentnumber
. studentnumber
你会用grades[arraypos].studentnumber
。 While you read them in, keep a counter of how many there are. qsort
to sort the array. qsort
对数组进行排序。 Edit 2 编辑2
FILE *cfPtr;
FILE *cfPtr;
member should not be in it. typedef struct { ... } Student;
typedef struct { ... } Student;
. Student
instead of struct Student
in the code. Student
而不是struct Student
。 Note that I capitalized the name (personal preference in naming to make it not look like a variable name). name = malloc( 50 * sizeof( struct student ));
name = malloc( 50 * sizeof( struct student ));
: name = malloc( 50 * sizeof( struct student ));
(or malloc( 50 * sizeof( Student ));
if you change it to use the typedef. That assumes there would not be 50 or fewer records to read from the file. malloc( 50 * sizeof( Student ));
如果将其更改为使用typedef,则假定从文件中读取的记录不超过50条。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.