Read word from file into simple linked list

孤人 提交于 2019-12-11 00:57:13

问题


I need to write a program to read from a file, then save the words into a linked list for further use. I decided to read the text character by character using fgetc, then save all into the list each time a newline ('\n') or space (' ') is detected, indicating one word. Sorry I'm a newbie in file pointers, this is what I've gotten so far:

struct list { //global
char string[30];
struct list *next;
};


int main(void) {

    FILE *filePtr;
    char file[] = "text.txt";
    char tempStr[30];
    list *curr, *header;
    char c;
    int i = 0;
    curr = NULL;
    header = NULL;

    if((filePtr = fopen(file, "r")) == NULL) {
        printf("\nError opening file!");
        getchar();
        exit(101);
    }
    printf("\nFile is opened for reading.\n");

    while(!EOF) {
        while((c = fgetc(filePtr) != ' ') && (c = fgetc(filePtr) != '\n')) {
            curr = (list*)malloc(sizeof(list));
            //c = fgetc(filePtr);
            tempStr[i] = fgetc(filePtr);
            i++;
            }

        tempStr[i] = '\0';

        strcpy(curr->string, tempStr);
        curr->next = header;
        header = curr;

        i = 0;
    }

    while(curr!=NULL) {
        printf("%s - ", curr->string); //This will not print.
        curr = curr->next;
    }

    if(fclose(filePtr) ==  EOF) {
        printf("\nError closing file!");
        getchar();
        exit(102);
    }
    printf("\nFile is closed.\n");

    getchar();
    getchar();

}

If the text file:

have a nice day

Desired output:

have - a - nice - day

But, I could not print out anything except the file opened and closed.

Thanks.


回答1:


Value of the macro EOF is -1, which is a system macro defined in stdio.h. File read APIs(fgetc, fread, fscanf) will return -1 once it reaches end of file. So in your program you have while(!EOF) this will be always false, because NOT of -1 is always 0. -1 will be represented in 2's complement so all bits of that variable will be 1. (If size of int is 2, -1 will be stored as 0xFFFF in int variable).

Use the below sample code.

while(EOF != (c = fgetc(filePtr))) 
{

    if ((c == ' ') || (c == '\n'))
    {
        if (i == 0)
        {
            continue;
        }

        tempStr[i] = '\0';
        i = 0;

        //here do your linklist node creation and insertion operation

           continue;
    }

    tempStr[i] = c;
    i++;
}



回答2:


while(!EOF) {

This is a constant condition that is always false, so you never read anything.

Your code also has other problems, such as doing

curr = (list*)malloc(sizeof(list));

in a loop but using curr outside the loop.




回答3:


You should replace the while condition with whatever function you're using to read the file - are you sure fgets isn't horrendously more efficient than this?

IE read the string into a much larger buffer than you expect, then copy it into an appropriately sized buffer and attach that to the node.




回答4:


  • This is always false:

    while(!EOF)
    
  • Review your memory allocation code.

    curr = (list*)malloc(sizeof(list))
    
  • Files may not have newlines at the end of the file.

    while((c = fgetc(filePtr) != ' ') && (c = fgetc(filePtr) != '\n'))
    



回答5:


Spoiler:

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

struct list {
    struct list *next;
    char string[30];
    };

int main(void) {

    FILE *fp;
    char file[] = "llist4.c";
     /* in C you CANNOT omit the "struct keyword" from a declaration or definition. */
    struct list *head=NULL, **pp= &head;
    int ch; /* getc() returns an int */
    size_t len ;
    char buff[30];

    fp = fopen(file, "r");
    if (!fp) {
        fprintf(stderr, "\nError opening file!");
        exit(EXIT_FAILURE);
    }
    printf("\nFile has been opened for reading.\n");

    for (len=0; len < sizeof buff;   ) {
        ch = fgetc(fp);
        if (ch == EOF && !len) break;
        if (ch == ' ' || ch ==  '\n' || ch == EOF) {
            if (!len) continue;
            buff[len] = '\0';
            *pp = malloc(sizeof **pp);
            if (!*pp) break;
            strcpy((*pp)->string, buff);
            (*pp)->next = NULL;
            pp = &(*pp)->next ;
            len=0; continue;
            }

        buff[len++] = ch;
    }

    if (len) {
        fprintf(stderr, "\nWord was too large, or out of memory\n");
        }

    for( ;head; head= head->next) {
        printf("%s - ", head->string);
    }

    if (fclose(fp) ==  EOF) {
        fprintf(stderr, "\nError closing file!\n");
        exit(EXIT_FAILURE);
    }
    printf("\nFile has been closed.\n");
exit(EXIT_SUCCESS);
}


来源:https://stackoverflow.com/questions/11168381/read-word-from-file-into-simple-linked-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!