我试图从一个文本文件读入一个链接列表。文本文件的书名、作者和年份用“:”分隔。每本书都在一个单独的行上。文本文件条目如下所示:

Absalom, Absalom!:William Faulkner:1936
After Many a Summer Dies the Swan:Aldous Huxley:1939
Ah, Wilderness!:Eugene O'Neill:1933

我从头开始重写。如有意见,将不胜感激。
#include <stdlib.h>
#include <stdio.h>

struct BookNode
{
    char linebuffer[128];
    char delim[]=":";
    char * Title[50];
    char * Author[50];
    char * Year[5];
    struct BookNode *next;
//    char *token = NULL;
};

int main(void)
{
    static const char booklist[]= "booklist.txt";
FILE *fr=fopen("booklist.txt", "r");
if ( fr != NULL)

{
char Title[50];
char Author[50];
char Year[5]
struct BookNode Booknode;
while (fgets(linebuffer,128, fr) != NULL &&
    sscanf(line, "%49s %49s %4s",
        &BookNode.Title, BookNode.Author, BookNode.Year)==3)
    {
         printf("%50s %50s %5s",
                BookNode.Title, BookNode.Author, BookNode.Year);
    }
}

最佳答案

你的代码现在有很多问题。
第一个(我没骗你)是代码格式化和缩进。粘贴的示例没有常规格式或缩进。即使在这样的短示例中,也很难遵循代码流。总是缩进你的代码,选择一个编码风格(有几个)并坚持它。
关于代码流,第一个问题是错误检查。即,检查fopen返回状态,但如果打开文件失败,则不采取足够的操作。
第二个问题是概念问题。你似乎没有意识到N个字符的数组只能容纳长度为N-1的字符串。因此,char[4]几乎不适合作为字符串存储年份。
既然已经解决了这些问题,下面是在任何情况下都会阻止代码工作的实际缺陷:
1)函数将一直读取,直到它填满缓冲区或到达行尾或文件尾字符为止。然而,您仍然需要调用fgets三次来尝试读取文件中的一行条目。你不太可能想做什么。你必须重新考虑你的循环内容。
2)您的“主”回路状态可能有缺陷。对于fgets&co的使用,这是一个非常常见的误解。假设您的数据文件在结尾处包含一个换行符(并且只有这样做才是正常的),那么您的循环将执行过多的一次。
最好这样构造读线循环:

while (fgets(buffer, BUF_SIZE, stdin)) { /* parse buffer */ }

3)代码中的内存管理存在基本问题:即函数feof无法分配内存来存储记录。相反,链接列表中的所有条目将指向在addEntry函数中分配的相同共享缓冲区。
有几种方法可以解决这个问题。一种是为main结构的每个成员(mallocBookNodetitle)使用多个对author的调用。另一种可能更可取的方法是使用可变大小的结构,例如:
struct BookNode {
    char *title;
    char *author;
    char *year;
    struct BookNode *next;
    char buffer[]; // this shorthand requires C99
};

为每个year分配足够的存储空间,以便可以在其中复制共享缓冲区的内容。struct BookNodetitleauthor然后指向此附加存储。这样就不会在循环的下一次迭代中覆盖其他BookNodes的内容。只需要一个year就可以释放整个节点。
我可能没有在这里列出你代码中的所有问题。也许您应该首先尝试处理一个较小的子问题,比如从free读取一个条目并从中构建,而不是另一个重写?

关于c - C:将文字读入链表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10870235/

10-10 12:29