2013-10-04 31 views
4

我正在讀取一個文件,並希望將每行放入數組中的一個字符串中。文件的長度是任意的,每行的長度是任意的(儘管假設它少於100個字符)。將文件的每一行讀入數組

這是我得到的,它不是編譯。從本質上講,這是一個字符數組的數組,對嗎?所以不應該是char** words = (**char)malloc(sizeof(*char));

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

int main(){ 


int BUFSIZE = 32767;//max number of lines to read 
char** words = (**char)malloc(sizeof(*char));//gives error: expected expression before 'char' 
FILE *fp = fopen("coll.txt", "r"); 
if (fp == 0){ 
     fprintf(stderr, "Error opening file"); 
     exit(1); 
} 

int i = 0; 
words[i] = malloc(BUFSIZE); 
while(fscanf(fp, "%100s", words[i]) == 1)//no line will be longer than 100 
{ 
     i++; 
     words[i] = realloc(words, sizeof(char*)*i); 
} 

int j; 
for(j = 0; j < i; j++) 
    printf("%s\n", words); 

return 0; 
} 

注:我讀過「Reading from a file and storing in array」但它並沒有回答我的問題。

+0

應該是char * ...你正在努力尋找字符指針的大小... – AurA

+1

請注意,'%100s'將會(a)跳過前導空白並在非空白字符後的空白處停止讀取,並且(b)會將大小爲100的緩衝區溢出一個字節,這可能很重要。您必須在轉換規範中指定一個小於數組大小的值。 –

回答

10

你的程序有幾個問題。 realloc()語句未正確使用。我也更喜歡fgets()來獲得一條線。這是我的解決方案。這也使用realloc()來增加緩衝區行的分配,這樣您就不必事先知道行數,也不必通過兩遍讀取文件(以更快的速度讀取)。當你不知道你需要預先分配多少內存時,這是一種常用的技術。

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

int main(void) 

    { 
    int lines_allocated = 128; 
    int max_line_len = 100; 

    /* Allocate lines of text */ 
    char **words = (char **)malloc(sizeof(char*)*lines_allocated); 
    if (words==NULL) 
     { 
     fprintf(stderr,"Out of memory (1).\n"); 
     exit(1); 
     } 

    FILE *fp = fopen("coll.txt", "r"); 
    if (fp == NULL) 
     { 
     fprintf(stderr,"Error opening file.\n"); 
     exit(2); 
     } 

    int i; 
    for (i=0;1;i++) 
     { 
     int j; 

     /* Have we gone over our line allocation? */ 
     if (i >= lines_allocated) 
      { 
      int new_size; 

      /* Double our allocation and re-allocate */ 
      new_size = lines_allocated*2; 
      words = (char **)realloc(words,sizeof(char*)*new_size); 
      if (words==NULL) 
       { 
       fprintf(stderr,"Out of memory.\n"); 
       exit(3); 
       } 
      lines_allocated = new_size; 
      } 
     /* Allocate space for the next line */ 
     words[i] = malloc(max_line_len); 
     if (words[i]==NULL) 
      { 
      fprintf(stderr,"Out of memory (3).\n"); 
      exit(4); 
      } 
     if (fgets(words[i],max_line_len-1,fp)==NULL) 
      break; 

     /* Get rid of CR or LF at end of line */ 
     for (j=strlen(words[i])-1;j>=0 && (words[i][j]=='\n' || words[i][j]=='\r');j--) 
      ; 
     words[i][j+1]='\0'; 
     } 
    /* Close file */ 
    fclose(fp); 

    int j; 
    for(j = 0; j < i; j++) 
     printf("%s\n", words[j]); 

    /* Good practice to free memory */ 
    for (;i>=0;i--) 
     free(words[i]); 
    free(words); 
    return 0; 
    } 
+1

+1。我強烈建議將「for」循環體的分號放在一行上。當在左括號之後附加到同一行時,它很容易被誤認爲是拼寫錯誤,或者被忽略。名義上,你可以在一行上有幾個「\ r」字符;它可能很重要(但更可能不會)。 –

+0

@JonathanLeffler - 我實施了你的建議。謝謝。 – willus

+1

@willus你是如何決定'int lines_allocated'的值128的? – Celeritas

0

你應該改變行:

char** words = (**char)malloc(sizeof(*char)); 

到這一點:

char** words=(char **)malloc(sizeof(char *)*Max_Lines);