2016-04-16 2 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

Смежные вопросы