【问题标题】:Read word from file into simple linked list将文件中的单词读入简单链表
【发布时间】:2012-06-25 11:19:11
【问题描述】:

我需要编写一个程序来读取文件,然后将单词保存到链表中以供进一步使用。我决定使用 fgetc 逐个字符地读取文本,然后在每次检测到换行符 ('\n') 或空格 (' ') 时将所有内容保存到列表中,表示一个单词。 对不起,我是文件指针的新手,这是我到目前为止所得到的:

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

}

如果是文本文件:

have a nice day

期望的输出:

have - a - nice - day

但是,除了打开和关闭的文件之外,我无法打印任何内容。

谢谢。

【问题讨论】:

    标签: c pointers file-io linked-list


    【解决方案1】:
    • 这总是错误的:

      while(!EOF)
      
    • 查看您的内存分配代码。

      curr = (list*)malloc(sizeof(list))
      
    • 文件的末尾可能没有换行符。

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

    【讨论】:

      【解决方案2】:
      while(!EOF) {
      

      这是一个始终为假的恒定条件,因此您永远不会阅读任何内容。

      你的代码还有其他问题,比如做

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

      在循环中,但在循环外使用 curr。

      【讨论】:

        【解决方案3】:

        你应该用你用来读取文件的任何函数替换 while 条件 - 你确定 fgets 没有比这更有效吗?

        IE 将字符串读取到比您预期大得多的缓冲区中,然后将其复制到适当大小的缓冲区中并将其附加到节点。

        【讨论】:

          【解决方案4】:

          EOF的值为-1,这是stdio.h中定义的系统宏。文件读取 API(fgetcfreadfscanf)在到达文件末尾时将返回 -1。所以在你的程序中你有while(!EOF),这总是错误的,因为-1NOT总是0。-1将用2的补码表示,所以该变量的所有位都是1。(如果大小为int 为 2,-1 将作为 0xFFFF 存储在 int 变量中)。

          使用下面的示例代码。

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

          【讨论】:

          • 会做,非常感谢,代码现在可以工作了。唯一的问题是每次我 printf 这个词都会被反转,例如从文件:'june 2012' 将导致输出:'2102 enuj'。我尝试编辑我的 struct header 和 temp 的顺序,但似乎仍然不起作用。 :(
          【解决方案5】:

          剧透:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-06-04
            • 1970-01-01
            • 2016-08-10
            • 1970-01-01
            • 2021-10-26
            • 2016-08-06
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多