2014-12-27 19 views
0
char *lessons[100]; 
FILE *lessonsptr; 

lessonsptr = fopen("lessons.txt", "r"); 

fscanf(lessonsptr, "%d", &N); 
char str[100]; 
while (!feof(lessonsptr)) 
{ 
    fgets(str, 100, lessonsptr); 
    lessons[i] = str; 
    i++; 
} 

fclose(lessonsptr); 

存儲到指針數組在while塊,我想從文件中讀取一個字符串,並將其存儲在lessons[i],但是這個代碼掃描與換行。我嘗試了其他方式,例如使用fscanf%[^\n],但它們不起作用。我怎樣才能得到它的工作?如何閱讀N個字符串,並將其在C

p.s. lessons.txt中的第一行是字符串的數量。這就是爲什麼我讀線的整數6.

+0

如果你的意思是在換行符到字符串讀取,那麼就讓它,事後刪除換行符 –

+0

此外,您還需要爲每節課分配空間,從'str'複製字符串到這個新空間。現在,lesson數組中的所有條目都會以'str'結尾,它只是'str'數組的地址,它只包含從文件讀取的最後一課。 –

+0

而且你不讀取N個條目,但讀取的文件數量與文件包含的數量相同。如果超過100,你將走出課程陣列的末尾......並且你不檢查fopen的結果以查看它是否工作等等。 –

回答

2

你的代碼是錯誤的兩個景點:

  • 你不應該閱讀while(!feof(...)),並
  • 你需要你去

你做緩衝的副本可以這樣做:

while (fgets(str, 100, lessonsptr)) { 
    lessons[i] = malloc(strlen(str)+1); // Add 1 for '\0' terminator 
    strcpy(lessons[i], str); // Copy the string into the allocated space 
    i++; 
} 

或者,因爲你知道有多少行會有你的文件,你可以做一個for環路N

for (int = 0 ; i != N ; i++) { 
    fgets(str, 100, lessonsptr); 
    lessons[i] = malloc(strlen(str)+1); 
    strcpy(lessons[i], str); 
} 

注意,由於使用了動態內存分配,你需要調用free(lessons[i])在一個循環在程序結束時。

另一個說明:你也可以使用strdup,但它不是C標準庫的一部分。

+0

@Jasen謝謝,現在已修復。 – dasblinkenlight

+0

我懶得修復的另一個問題是,任何超過98個字符的行都會被分成兩個問題。 – Jasen

+0

@Jasen這當然也是如此。不過,我認爲OP知道這個限制。 – dasblinkenlight

0

這裏有一個方法:

char str[100][100]; 
    while (!feof(lessonsptr) && i<100) 
    { 
     if(!fgets(str[i], 100, lessonsptr)) 
      break; 
     lessons[i] = str[i]; 
     i++; 
    } 

,如果你允許函數getline這可能是更好:

while (!feof(lessonsptr) && i<100) 
    { 
     if(0>(lessons[i] = getline(NULL,NULL,lessonptr))) 
       break; 
     i++; 
    } 

但因爲你有數量在變量N 中的教訓(你應該在C中使用小寫變量) 你可以像這樣做初始化。

char **lessone=NULL; 
int (*str)[100]; // if not using getline() 

/* 
... 
*/ 

    fscanf(lessonsptr, "%d\n", &N); // need \n to read a whole line 
    lessons=calloc(sizeof(char*),N); 

    str=malloc(100*N); // if not using getline() 

    while (!feof(lessonsptr) && i<N) 
+0

似乎沒有人喜歡這個 – Jasen

+1

代碼使用'feof()'是錯誤的。代碼需要測試'fgets()'的結果。 – chux

+0

感謝您的解釋。 – Jasen

1
there were many problems with the code. 
the following compiles cleanly 
However, I have not run it. 

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

#define MAX_LINE_LENGTH (100) 

void cleanup(char **, int); 

int main() 
{ 
    int N = 0; // count of data line in file 

    FILE *lessonsptr; 

    if(NULL == (lessonsptr = fopen("lesson.txt", "r"))) 
    { // then fopen failed 
     perror("fopen failed for lesson.txt"); 
     exit(EXIT_FAILURE); 
    } 

    // implied else, fopen successful 

    // get count of following lines 
    if(1 != fscanf(lessonsptr, " %d \n", &N)) 
    { // then, fscanf for line count failed 
     perror("fscanf failed for line count"); 
     fclose(lessonsptr); 
     exit(EXIT_FAILURE); 
    } 

    // implied else, fscanf for line count successful 

    char **lessons = NULL; 
    int i = 0; // loop counter 
    if(NULL == (lessons = malloc(N*sizeof(char*)))) 
    { // then malloc failed 
     perror("malloc failed for lessons"); 
     fclose(lessonsptr); 
     exit(EXIT_FAILURE); 
    } 

    // implied else, malloc successful for lessons 

    // set all lessons[] to NULL 
    memset(lessons, 0x00, (N*sizeof(char*))); 

    for(i=0; i< N; i++) 
    { 
     if(NULL == (lessons[i] = malloc(MAX_LINE_LENGTH))) 
     { // then, malloc failed 
      perror("malloc failed for lessons[]"); 
      fclose(lessonsptr); 
      cleanup(lessons, N); 
      exit(EXIT_FAILURE); 
     } 

     // implied else, malloc successful for lessons[i] 

     // clear the malloc'd memory 
     memset(lessons[i], 0x00, MAX_LINE_LENGTH); 
    } 

    char str[MAX_LINE_LENGTH] = {'\0'}; 

    for(i = 0; i<N; i++) 
    { 
     if(NULL == fgets(str, MAX_LINE_LENGTH, lessonsptr)) 
     { // then file did not contain enough lines 
      perror("fgets failed"); 
      fclose(lessonsptr); 
      cleanup(lessons, N); 
      exit(EXIT_FAILURE); 
     } 

     // implied else, fgets successful 

     // copy line to where lessons[i] points 
     memcpy(lessons[i], str, MAX_LINE_LENGTH); 

     // prep for next input line 
     memset(str, 0x00, MAX_LINE_LENGTH); 
    } // end for 

    fclose(lessonsptr); 
    cleanup(lessons, N); 
    return(0); 
} // end function: main 

void cleanup(char **lessons, int N) 
{ 
    int i; // loop counter 
    for(i=0; i<N; i++) 
    { 
     free(lessons[i]); 
    } 
    free(lessons); 
} // end function: cleanup 
相關問題