C中的Fgets和EOF

时间:2013-11-26 22:28:13

标签: c eof fgets

我需要知道如何使用fgets从文件中读取所有记录我不明白如何使用while循环读取所有记录。因为如果我像这样写循环我得到运行时错误可能是什么错误?谢谢。

N=15;     
sakums:  
 struct studenti students[N];     
       char line[100];
   char *ptk; char * end; int i;int sorted;
    int g=0,ch,count=0;
    int n;
    int choice;
   FILE *fails_st = fopen("studenti.txt", "r+");
    printf("\n1.Show data  ");   
 scanf("%d",&choice); 
if(choice==1)
        while (fgets(line, sizeof(line), fails_st) != NULL)         
   {               
     students[i].Nr = strtol(line, &end, 10);
     ptk = strtok(line, " ");
     ptk = strtok(NULL, " ");
     strcpy(students[i].name, ptk);
     ptk = strtok(NULL, " ");
     strcpy(students[i].surname, ptk);
     ptk = strtok(NULL, ".");
     end = (ptk + strlen(ptk));
     students[i].dzd.da_day = strtol(ptk, &end, 10);
     ptk = strtok(NULL, ".");
     end = (ptk + strlen(ptk));
     students[i].dzd.da_month = strtol(ptk, &end, 10);
     ptk = strtok(NULL, " ");
     end = (ptk + strlen(ptk));
     students[i].dzd.da_year = strtol(ptk, &end, 10);
     ptk = strtok(NULL, " ");
     students[i].dzimums = *ptk;
   }
   fclose(fails_st);
       printf("Student list\n");
   printf("%d. %s %s %d.%d.%d %c\n", students[i].Nr, students[i].name, 
          students[i].surname, students[i].dzd.da_day, 
          students[i].dzd.da_month, students[i].dzd.da_year, 
          students[i].dzimums);       

我的第一个循环是这样的,但它只检查记录的常数。

  for(i=0; i < N && fgets(line, sizeof(line), fails_st) != NULL; i++)

2 个答案:

答案 0 :(得分:2)

您的文件中可能包含N条以上的记录。目前,只要您阅读更多内容,就会溢出阵列。您将需要使用动态内存分配:

struct studenti *students = NULL;
int max_students = 0;
int num_students = 0;
const int grow_amount = N;

while ( fgets(line, sizeof(line), fails_st) ) {
    if( num_students >= max_students ) {
        max_students += grow_amount;
        students = realloc( students, max_students * sizeof(struct studenti) );
    }

    // TODO: Read data into students[num_students]

    num_students++;
}

// When done with the memory, don't forget to free it.
free(students);

答案 1 :(得分:1)

fgets您的问题 <。相反,它是这个部分:

struct studenti students[N];

如果要支持任意数量的记录,则需要将其设置为动态分配,并在达到当前大小限制时调整其大小(使用realloc)。该代码看起来像这样:

size_t max_students = N;
size_t i = 0;
struct studenti *students = malloc(max_students * sizeof(struct studenti));
while (fgets(line, sizeof(line), fails_st))
{
    if (i == max_students)
    {
        max_students *= 2;
        students = realloc(students, max_students * sizeof(struct studenti));
    }
    /* parse `line` into `students[i]` as you are currently doing */
    i++;
}

错误处理作为练习留下。