簡體   English   中英

使程序讀取文件的某些部分

[英]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的格式說明符(%s)少於參數。
  • 問題為“您想做什么”的第三個printf缺少結尾括號。
  • fprintf不正確; 它應該具有文件句柄作為第一個參數。 但是,我懷疑這可能是printf嗎?
  • 最后的while循環在其結束括號后有一個多余的分號(;),這意味着它的主體為空,而不是表面上預期的printfswitch語句。
  • switch語句有點奇怪。 我認為這是“未完成”的部分。 但是將fclose包括在內似乎很奇怪。 它可能應該在else主體的末尾。
  • 使用system("PAUSE"); 也許不是最佳選擇。 也許使用getch暫停輸入會更有意義。

編輯這里是一些其他信息,以回應您的評論,要求提供更多詳細信息。 在我看來,這聽起來像是功課,因此僅給出答案似乎並不正確。 但這是一種方法:

  • 用文件中的6個項目定義一個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 請注意,我將名稱大寫(命名時出於個人喜好,使其看起來不像變量名)。
  • 對於malloc,您很接近。 但是按照書面規定,它正在為單個記錄分配空間。 您將需要這樣的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM