2016-04-16 16 views
2

我想加載一個文件到我的程序中,這樣我就可以在單個基礎上處理字節,但是當我加載文件時,它會提前停止加載;總是由1個字符組成。如果文件中只有一個字符,則不會加載它。我是如何閱讀文件的問題,還是在不同的位置?fgetc無法加載文件的最後一個字符

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

typedef struct node {//linked list structure, I use this because I am working with files of vastly varying length 
    char val; 
    struct node *next; 
} data; 

void printdata(data *head); 
void freeData(data **head); 
data* readFile(FILE *f); 

void main(int argc, char *argv[]) {//set this up so it is easier to test 
    if(argc == 2) { 
     FILE *f = fopen(argv[1], "r"); 
     data *d = readFile(f); 
     fclose(f); 
     printdata(d); 
     freeData(&d); 
    } 
} 

data* readFile(FILE *f) {//This is the function containing the problem 
    data *retVal = malloc(sizeof(data)); 
    data *cur = retVal; 
    int c = fgetc(f); 
    if(c != EOF) { 
     retVal->val = (char) c; 
     while((c = fgetc(f)) != EOF) { 
      cur->next = malloc(sizeof(data)); 
      cur->next->val = (char) c; 
      cur = cur->next; 
     } 
    } else return NULL;//EDIT: was in a rush and forgot to add this. 
    cur->next = NULL; 
    return retVal; 
} 

void freeData(data **head) { 
    if((*head)->next != NULL) freeData(&((*head)->next)); 
    free(*head); 
} 

void printdata(data *head) { 
    data *cur = head; 
    do { 
     printf("%c", cur->val); 
     cur = cur->next; 
    } while(cur->next != NULL);//EDIT: I changed this because there was a small "problem" that was not the real problem 
    printf("\n"); 
} 
+5

問題出在你的'printdata'函數中,它不打印列表中的最後一個元素。 – Barmar

+3

您的設計對空文件無法正常工作。它會返回一個單獨的節點,該節點在'val'中有一個未初始化的值。 – Barmar

+0

它是否產生任何錯誤? –

回答

1

printdata()停止過早。 @Barmar

不要停止當cur->next == NULL。停止時cur == NULL

void printdata(data *head) { 
    data *cur = head; 
    while (cur) { 
    printf(" <%hhx>", cur->val); // Changed format for debugging 
    fflush(stdout);    // Useful for debugging 
    cur = cur->next; 
    } 
    printf("\n"); 
} 

還包括的是一個簡化的readFile()

data* readFile(FILE *f) { //This is the function containing the problem 
    data head; // Only next field used 
    data *cur = &head; 
    int c; 
    while ((c = fgetc(f)) != EOF) { 
     cur->next = malloc(sizeof *(cur->next)); 
     cur = cur->next; 
     assert(cur); 
     cur->val = (char) c; 
    } 
    cur->next = NULL; 
    return head.next; 
} 
1

讓我們來看看功能printdata()

void printdata(data *head) { 
    data *cur = head; 
    while(cur->next != NULL) { 
     printf("%c", cur->val); 
     cur = cur->next; 
    } 
    printf("\n"); 
} 

注意,當

cur->next == NULL 

的同時,內部的命令將執行。

另請注意,這總是發生在最後一個元素。所以你的代碼不會打印最後的數據。

在其他的解決方案,你可以使用一個do-while循環:

do{ 
    printf("%c", cur->val) 
    cur = cur->next; 
} while (cur->next != NULL); 

這將保證最後一個元素將打印,因爲同時會停止循環內部的執行最後一個元素。

希望這會有所幫助。

+0

這不是問題,我嘗試了更改,問題仍然存在以相同的方式。儘管感謝 –

+0

這是不幸的。我確實相信「盡力而爲」是一種改進,但我明白它是否不是問題的根源。我今晚被燒壞了,但如果你的問題在明天站立,我會再看看! – Luanf

相關問題