C 使程序读取文件的某些部分

C 使程序读取文件的某些部分,c,file,sorting,C,File,Sorting,我有一个包含学生姓名和成绩的文件,我想写一个程序,可以根据用户选择对他们的成绩进行排序(比如期中1、期中2)。我写了选择部分并打开了文件,但我不知道如何使程序只读取文件的某些部分(例如只读取期中1年级)并只对它们进行排序。这是我到目前为止写的东西 #include <stdio.h> #include <stdlib.h> typedef struct { int number; char name[30]; char surname[30]; int midterm1

我有一个包含学生姓名和成绩的文件,我想写一个程序,可以根据用户选择对他们的成绩进行排序(比如期中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;
    }
#包括
#包括
类型定义结构{
整数;
字符名[30];
查氏[30];
国际中期1、中期2、中期3;
}学生;
int main()
{
智力选择,学生人数,期中1,期中2,期中3;
姓氏;
文件*cfPtr;
结构学生*姓名;
name=malloc(10*sizeof(学生));
如果((cfPtr=fopen(“grades.txt”,“r”))==NULL)
printf(“无法打开文件。\n”);
否则{
const int STUDENTSMAX=100;
学生[STUDENTSMAX];
int i=0;
而(!feof(cfPtr))
{
fscanf(cfPtr,“%d%s%s%d%d%d”,&students[i]。编号,&students[i]。姓名,&students[i]。姓氏,&students[i]。期中1,&students[i]。期中2,&students[i]。期中3);
printf(“%4d%15s%15s%10d%10d%10d\n”,学生[i]。编号,学生[i]。姓名,学生[i]。姓氏,学生[i]。期中1,学生[i]。期中2,学生[i]。期中3);
i++;
}
printf(“您想做什么?\n”
“1-根据期中1进行排序\n”
“2-根据期中2进行排序\n”
“3-根据期中3进行排序\n”
“4-退出\n”);
scanf(“%d”,选择(&C);
while(选项!=4){
开关(选择){
案例1:
qsort(学生,10人,国际学生,综合学生);

对于(i=0;i给定的可能是某种自由格式的文本文件(基于显示的代码),仅读取整个文件可能是有意义的(有点像您已经在做的事情)并且只使用您需要的部分。如果文本文件具有固定偏移量的非常特定的格式,您可以查找文件中的某些位置并读取特定的列值,然后查找下一个偏移量并从下一行读取列值。但这可能比它的值更麻烦,效率也不会更高(如果有的话)

话虽如此,要对结果进行排序,您可能还是需要整个文件。例如,如果您只是阅读并排序“期中1”值,那么结果将被排序没有任何相关的名称和学生编号。因此,如果不知道更多关于目标,你可以考虑创建一个<代码> Stutt,它可以保存一行(学生编号、姓名、姓氏、MIDTM1等)。。然后创建一个数组,并将每一行读取到数组的一个元素中。如果您知道前面有多少行,则可以将数组分配到一个块中,否则可能需要在增长数组时重新分配它

读取整个数组后,可以根据所需的值进行排序(例如,使用

提到这一点后,现有代码中存在一些问题:

  • 第二个printf的格式说明符(%s)少于参数
  • 带“你想做什么”问题的第三个printf缺少结尾部分
  • fprintf不正确;它应该有一个文件句柄作为第一个参数。不过,我怀疑它可能是
    printf
  • 最后一个
    while
    循环在其结束符后面有一个无关的分号(;),这意味着它的正文是空的,而不是明显想要的
    printf
    switch
    语句
  • switch
    语句编写时有点奇怪。我假设这是“未完成”的部分。但将
    fclose
    包含在其中似乎很奇怪。它可能位于主
    else
    的末尾
  • 使用
    system(“PAUSE”);
    可能不是最佳选择。使用
    getch
    可能会使暂停输入更有意义
编辑以下是一些附加信息,以回应您的评论,询问更多细节。这听起来像是家庭作业,因此仅给出答案似乎不太合适。但这里有一种方法:

  • 使用文件中的6个项定义一个
    struct
    (基本上是放入当前定义为局部变量的6个变量)
  • 将局部变量(例如,
    grades
    )声明为指向所定义结构的
    指针
  • 使用
    malloc
    分配内存并将其分配给刚才提到的指针。内存量可能是整个过程中最棘手的部分。
    malloc
    的size参数类似于
    numRecs*sizeof(yourstruct)
    。问题是
    numRecs
    应该是什么。如果这是一个作业,并且你被告知会有多少条记录(最多),那么就使用它。如果它是“未知的”,那么有两种处理方法。一种是猜测一个数字(例如,100)然后在循环中读取它们时,如果超过100,则使用
    realloc
    。另一种选择(可能效率较低)是使用两个循环-在不存储它们的情况下读取一次,但只需对它们进行计数,然后分配已知大小并再次读取。我将使用realloc版本
  • 将局部变量的使用替换为数组(即
    malloc
    ed)。例如,不使用
    studentnumber
    而是使用
    grades[arraypos].studentnumber
    。读入时,保留一个计数器,指示有多少个。然后可以使用
    qsort
    对数组进行排序
编辑2

  • 结构定义看起来是正确的,除了
    文件*cfPtr;
    成员不应该在其中。它仍然应该是一个局部变量
  • 为了便于使用,您可以将结构定义为
    typedef struct{…}Student;
    。这样您就可以使用
    Student
    而不是
    struct Student<