简体   繁体   English

将文件中的单词读入简单的链接列表

[英]Read word from file into simple linked list

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. 我决定使用fgetc逐个字符地读取文本,然后在每次检测到换行符( '\\n' )或空格( ' ' )时将所有单词保存到列表中,以表示一个单词。 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. 谢谢。

Value of the macro EOF is -1 , which is a system macro defined in stdio.h . EOF值为-1 ,这是stdio.h定义的系统宏。 File read APIs( fgetc , fread , fscanf ) will return -1 once it reaches end of file. 文件读取API( fgetcfreadfscanf )到达文件末尾时将返回-1。 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). 因此,在您的程序中, while(!EOF)始终为false,因为-1 NOT始终为0。 -1将以2的补码表示,因此该变量的所有位均为1。(如果int大小为2, -1将作为0xFFFF存储在int变量中)。

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++;
}
  • 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')) 
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. 在循环中,但在循环外使用curr。

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? 您应该用读取文件时使用的任何函数替换while条件-您确定fgets的效率不比这高吗?

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. IE将字符串读取到比您期望的要大得多的缓冲区中,然后将其复制到适当大小的缓冲区中并将其附加到节点。

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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM