2012-03-25 25 views
3

這是我的結構計劃不想要讀取文件

typedef struct { 
     char mmsi[10]; 
     char name[20]; 
     double latitude; 
     double longitude; 
     int course; 
     double speed; 
    }Vessel; 

這是我的功能,不想要工作

void searchByLatLong(double latitude, double longitude){ 
     FILE * file; 
     struct dirent *drnt; 
     DIR * dir = opendir("./text"); 
     char *path = (char *)malloc(19); 
     Vessel *vessel = (Vessel *)malloc(sizeof(Vessel)); 

     while((drnt = readdir(dir)) != NULL) { 
      if(strcmp(drnt->d_name,".") && strcmp(drnt->d_name,"..")) { 

       strcpy(path,"text/"); 
       strcat(path,drnt->d_name); 

       file=fopen(path, "r"); 
       fscanf(file," %s %[a-zA-Z0-9 ]19s %lf %lf %d %lf", &vessel->mmsi,&vessel->name,&vessel->latitude,&vessel->longitude,&vessel->course,&vessel->speed); 

     // if (mmsi+".txt" == drnt->d_name){ 
        printf("%s\n%s\n%lf\n%lf\n%d\n%lf\n\n",vessel->mmsi,vessel->name,vessel->latitude,vessel->longitude,vessel->course,vessel->speed); 
      //} 


      fclose(file); 
     } 
     seekdir(dir, telldir(dir)); 

    // if(this->mmsi == mmsi){ 
     // printVessel(); 
    // } 

    } 
    closedir(dir); 
} 

當我嘗試加載它加載只有兩個第一字符串,然後txt文件之後它會記住一些垃圾。數據加載到另一個變量改變不了什麼;/ 這是應該被加載的樣品txt文件:

3 
RMS Titanic 
22.222 
33.333 
4 
5.9 
+0

在任何情況下,您應該添加一些錯誤檢查到您的代碼。 'fscanf'返回一個非常有用的值 - 已成功讀取的項目數。這可能有助於找到真正的原因。 (當然,'fopen'也是如此。) – 2012-03-25 01:18:48

回答

2

問題在於你的格式字符串。正確的格式字符串是:

" %s %19[a-zA-Z0-9 ] %lf %lf %d %lf" 

字段寬度位於轉換說明符之前。另外,序列是一個轉換說明符,就像's'一樣。你看到的問題是fscanf()處理'3',因爲它匹配第一個%s。然後它處理'RMS泰坦尼克號',因爲它匹配%[a-zA-Z0-9 ],但之後處理停止,因爲輸入中沒有'19'。此時剩餘的參數未初始化。

您應該檢查fscanf()的返回值。它會告訴你實際執行了多少次轉換。

0

感謝張貼一個有趣的問題;我瞭解到fscanf()和它接受的[]表示法。

[]表示法指定正在讀取一個字符串,因此,您追加到的s被視爲應該匹配的文字字符。同樣,您提供的寬度說明符19應顯示在[]之前。

如果您有名爲「RMS Titanic19s」的船隻,您當前的代碼將開始工作。

你的fscanf更改爲:

fscanf(file," %s %19[a-zA-Z0-9 ] %lf %lf %d %lf", 
    vessel->mmsi,vessel->name,&vessel->latitude, 
    &vessel->longitude,&vessel->course,&vessel->speed); 

,你的代碼將開始工作。這些已經指向你想以填補緩衝區 -

通知我通過降低從char []成員mmsiname多餘&一些固定的編譯警告。在他們面前你不需要&。一種教學替代形式是&vessel->mmsi[0]-第一個字符mmsi的地址。