2016-12-05 120 views
-1

我有一個項目中的這2個函數加載並保存用戶的信息到一個文件中。每個用戶都保存在文件的新行中。我的問題是,當我嘗試使用ftell(f)時,程序崩潰。當我打印ftell(f)後,它用fopen()打開文件後打印-1。我嘗試在errno中看到錯誤,但是它在fopen()後打印出「NO ERROR」,但當我使用fseek修改文件指針f位置時,會顯示「INVALID ARGUMENT」。爲什麼ftell打印-1作爲文件指針的值?爲什麼errno打印出「INVALID ARGUMENT」?

我的問題是在我的Load_File函數,但我也顯示了Save_File函數也檢查我在文件中正確寫入。

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <string.h> 

LIST Load_File(LIST L){ 
    //PRE: receive a void list (L==NULL) 
    //POST: returns an user's loaded from file 
    USER user; //node of list 

    char str[150]; 

    //User's structure 
    char name[30]; 
    char CI[10]; 
    char email[30]; 
    char city[30]; 
    char password[30]; 

    errno=0; 

    FILE *f; 
    if(f=fopen("DATOS.txt","r")==NULL){ 
     printf("File not found. \n"); 
     return L; 
    } 


    //Code for verify what's happening 
    printf("FTELL: %d/n", ftell(f)); //prints -1 
    printf("ERRNO: %s\n", strerror(errno)); //prints NO ERROR 
    fseek(f, 0, SEEK_CUR); 
    printf("FTELL: %d\n", ftell(f)); //still prints -1 
    printf("ERRNO: %s\n", strerror(errno)); //prints INVALID ARGUMENT 
    printf("FEOF: %d\n",feof(f)); //CRASHES! (a) 

    while(feof(f)==0){ //CRASHES when (a) line is deleted 

     //Load line of file in user's structure 
     fgets(str, 150, f); 
     sscanf(str,"%s %s %s %s %s ",name, CI, email, city, password); 
     //Copy into structure's parts 
     strcpy(user->name, name); 
     strcpy(user->CI, CI); 
     strcpy(user->email, email); 
     strcpy(user->city, city); 
     strcpy(user->password, password); 

     Add_user_to_list(L, user); 
    } 

    if(fclose(f)!=0) printf("\n\n FILE NOT PROPERLY ClOSED \n\n"); 
} 

void Save_File(LIST L){ 
    //PRE: receive an user's list 
    //POST: saves a new list in file 

    FILE *f; 
    int flag=0; 

    f=fopen("DATOS.txt","w"); 
    if(f==NULL){ 
     printf("Error opening file f\n"); 
    } 
    if(!L_Void(L)){ 
     L=L_First(L); 
     do{ 
      if(flag) L=L_Next(L); 
      flag=1; 
      fprintf(f,"%s %s %s %s %s \n",L_InfoM(L)->name,L_InfoM(L)->CI, L_InfoM(L)->email, L_InfoM(L)->city, L_InfoM(L)->password); 
     }while(!L_Final(L)); 
    }else printf("List is void, then nothing was saved.\n"); 

    if(fclose(f)!=0) printf("\n\n FILE NOT PROPERLY COSED \n\n"); 
} 

回答

2

這段代碼是錯誤的:

if(f=fopen("DATOS.txt","r")==NULL){ 

二元運算 - 諸如== - 比賦值運算符的優先級高 - 這樣的=

if(f=(fopen("DATOS.txt","r")==NULL)){ 

邏輯==比較的結果被分配到f

所以當你的代碼解析。

你爲什麼把這個任務填入if聲明中?這是更清晰,以及作爲一個很多不太容易出錯:

FILE *f = fopen("DATOS.txt", "r"); 
if (NULL == f) { 
... 

可以在一行中做的越多,你就越有可能會犯錯誤。正確編程足夠困難。不要做那些讓它變得更難的事情 - 比如試着看看你可以將多少代碼放入一行。

+0

'(NULL == f)'是不必要的;你可以簡單地寫'(f)',因爲它基本上會自動與0進行比較。 –

+0

謝謝!我曾嘗試過兩行,但我當然誤解了時間的結果。至少這讓我強化了優先重要性! –

+0

@MDXF「'(NULL == f)'是不必要的;你可以簡單地寫'(f)'''(NULL == f)'相當於'(!f)'。現在你明白了爲什麼我傾向於實現與NULL的比較。 –