2014-07-08 130 views
0

我試圖讀取文件,將特定的標記放入結構中並讀取它們。構建結構陣列的問題

文件即時閱讀的格式如下

Edward is enrolled in CSE 1105. 
August is enrolled in CSE 1105. 
SoonWon is enrolled in MATH 1426. 

我的僞代碼,希望能夠幫助您按照

Open file 
send file to function create_structures to be tokenized 
read file fgets(), then tokenize strtok() by delimiter space 
name/course will be 1st and 5th token, add tokens to array of structures 

到目前爲止的代碼是

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

void create_structures(FILE* file); 

struct info{ 
    char name[20]; 
    char course[4]; 
}; 

int main() 
{ 
    FILE* fp = fopen("input-hw04b.txt","r"); 
    create_structures(fp); 

} 

voidcreate_structures(FILE* file) 
{ 
    struct info struct_array[30]; /* Correct? want struct to be like 
            strcut info struct_array = {{"Edward","1105."}, 
                   {"August","1105."}};ETC..*/ 
    char buffer[100]; 
    char* del = " "; 
    char* token; 
    int number,index,count; 

    while(fgets(buffer,sizeof(buffer),file) != NULL) 
    { 
     index = 0; 
     count = 0; 
     token = strtok(buffer,del); 
     while(token != NULL) 
     { 
      if(count == 0) 
      { 
       strcpy(struct_array[index].name,token); 
      } 
      if(count == 5) 
      { 
       strcpy(struct_array[index].course,token); 
      } 
      token = strtok(NULL,del); 
      count = count + 1; 
     } 
     index = index +1; 

     for (index = 0; index < count; index++) 
      printf("%s %s\n", struct_array[index].name, struct_array[index].course); 
    } 
} 

當我打印結構我得到以下輸出

Edward 1105. 

. 
� 

(�n�� � 
� 
�I9�� � 

August 1105. 

. 
� 

(�n�� � 
� 
�I9�� � 

SoonWon 1426. 

. 
� 

(�n�� � 
� 
�I9�� � 

任何人都知道所有這些額外的字符?我的朋友說,「問題是你試圖以同一確切結構存儲文件每一行的值。」但我並不真正瞭解他。這就是我想要做的,將它添加到結構數組中。

+0

我使用的strtok獲得名稱,所以我相信令牌是NULL終止 – Jovis13

回答

1

你必須移動外while循環的

for (index = 0; index < count; index++) 
     printf("%s %s\n", struct_array[index].name, struct_array[index].course); 

之外。

而且你有外while循環之前移動

index = 0; 

因爲現在會發生什麼是您嘗試打印您的N個條目N次(每次讀取新線時間)。不過,你老是寫到位0

更新。如果不是內部循環是簡單:

while(fgets(buffer,sizeof(buffer),file) != NULL) 
{ 
    token = strtok(buffer,del); 
    strcpy(struct_array[index].name,token); 
    token = strtok(buffer,del); 
    strcpy(struct_array[index].course,token); 
} 
+0

謝謝,它現在工作,顯然進入結構的過程現在是1105。八月所以現在我要弄清楚爲什麼它將名稱添加到coutrse的末尾 – Jovis13

+0

我想你應該刪除你的'if count == 0'和'if count == 5'語句,你已經知道條目結構,所以只需將第一個標記分配給名稱,將第二個標記分配給課程。 – Ashalynd

+0

,但有幾個標記,第二個標記將「是」,因爲即時通訊使用分隔符作爲空間,這就是爲什麼我計數令牌,因爲標記是「edward」「是」「註冊」「」CSE「」1105 「。 – Jovis13

1
struct info{ 
    char name[20]; 
    char course[4]; // make at least course[5] for null-termination 
}; 

您最初的問題是你沒有足夠的空間在過程中保持課程號。字符串需要+ 1個字符才能爲'\ 0'終止字符留出空間。

您有被搞亂你的打印額外的邏輯錯誤。看的,因爲它是閱讀如何打印每個記錄,以及如何打印所有記錄,您已經完成讀取文件後的想法如下:

int number,index,count; 
index = 0; 

while(fgets(buffer,sizeof(buffer),file) != NULL) 
{ 
    count = 0; 
    token = strtok(buffer,del); 
    while(token != NULL) 
    { 
     if(count == 0) 
     { 
      strcpy(struct_array[index].name,token); 
     } 
     if(count == 5) 
     { 
      strcpy(struct_array[index].course,token); 
     } 
     token = strtok(NULL,del); 
     count = count + 1; 
    } 

    /* to print each record as read, print before "index +1" */ 
    printf("%s %s\n", struct_array[index].name, struct_array[index].course); 

    index = index +1; 

} 

/* to print all records after you finish reading */ 
int iter = 0; 
for (iter = 0; iter < index; iter++) 
    printf("%s %s\n", struct_array[iter].name, struct_array[iter].course); 

你必須與你的分隔符進一步的問題。閱讀課程後,緩衝區中仍有.。您可治隨:

char del[] = " ."; 

您還可以清理你的邏輯和錯誤進一步檢查位有:

#include <errno.h> 
... 
char fname[] = "dat/courses.txt"; /* put your filename back in here */ 
FILE* fp = fopen(fname,"r"); 
if (fp == NULL) { 
    fprintf (stderr, "Couldn't open file %s; %s\n", fname, strerror (errno)); 
    exit (EXIT_FAILURE); 
} 
... 
char buffer[100]; 
char del[] = " ."; 
char* token; 
int index,count; 
index = 0; 

while(fgets(buffer,sizeof(buffer),file) != NULL) 
{ 
    count = 0; 

    token = strtok(buffer,del); 
    if (token != NULL) { 
     strcpy(struct_array[index].name,token); 
     count += 1; 
    } 

    while((token = strtok(NULL,del)) != NULL) 
    { 
     if(count == 5) 
     { 
      strcpy(struct_array[index].course,token); 
     } 

     count = count + 1; 
    } 

    index = index +1; 

} 

輸出:

struct_array[0] Edward 1105 
struct_array[1] August 1105 
struct_array[2] SoonWon 1426 
+0

其正確打印,但我無法找到課程錄入錯誤。當然,我希望它是像「1105」。但現在它的形式「1105.August」,所以我有另一個問題,任何邏輯錯誤,你可以真正快速發現? – Jovis13

+0

這絕對不是你想要的,給我一分鐘,我會再看看。 –

+0

@ user3686360我發現了你的'August'錯誤的來源,在讀完課程後還有其他字符保留在緩衝區中。更改分隔符可以解決問題。檢查更新的答案。 –