2013-11-26 85 views
-1

我需要知道如何使用fgets讀取文件中的所有記錄我不懂如何用while循環讀取所有記錄。因爲如果我寫這樣的循環,我得到運行時錯誤什麼可能是錯誤?謝謝。Fgets和EOF在C

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

您是要求我們調試代碼還是要求我們教您如何將數據讀入文件?如果你想讓我們調試你的代碼,我們至少需要知道'N'是什麼以及你提供了哪些數據。 (另外,如果你希望我們調試你的代碼,首先刪除任何不相關的代碼,測試一下你可以刪除哪些代碼,最有可能的是你自己會發現這個bug。) –

回答

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); 
+0

這很容易讓你失望用於在括號內部放置空格。或者對於線性而不是指數重新分配。或者使用過於冗長的循環索引變量名稱。 – zwol

+1

你是認真的嗎? – paddy

+0

關於括號內側的空格?絕對。那種風​​格讓我眼睛流血。 (但是你會注意到我並沒有真正地讓你失望。) – zwol

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++; 
} 

錯誤處理左作爲練習。