我最近开始学习C编程。我有一些java经验所以我知道我的代码方式,我喜欢思考.. 我正在做的这件小事就是杀了我。 我正在尝试制作一个程序来读取文本文件中的行 - >将其存储在单链表中 - >打印出单链表 到目前为止,这是我的代码:
typedef struct node {
char *data;
struct node *next;
} node;
node *start = NULL;
node *current;
void add(char *line) {
node *temp = malloc(sizeof(node));
// This line under I believe where my problem is...
temp->data = line;
temp->next = NULL;
current = start;
if(start == NULL) {
start = temp;
} else {
while(current->next != NULL) {
current = current->next;
}
current->next = temp;
}
}
这是我的函数,用于读取文件并将字符发送到添加功能
void readfile(char *filename) {
FILE *file = fopen(filename, "r");
if(file == NULL) {
exit(1);
}
char buffer[512];
while(fgets(buffer, sizeof(buffer), file) != NULL) {
// I've tried to just send i.e: "abc" to the add function
// which makes the program work.
// like: add("abc");
// my display method prints out abc, but when I'm sending buffer
// it prints out nothing
// Thing is, I've spent way to much time trying to figure out what
// I'm doing wrong here...
add(buffer);
}
fclose(file);
}
我确信这是一个相当简单的问题,但我花了太多时间来解决这个问题。 如果还有其他什么东西可以看起来/可能更好,我也很欣赏它的反馈:)
答案 0 :(得分:4)
尝试:
temp->data = strdup(line);
到dup
许可(复制)什么行指向。
否则每一行都指向buffer
,每一行都会被新行覆盖。
答案 1 :(得分:4)
您需要为字符串分配内存 - 每行都被读入buf,因此您需要将其复制出来,否则将被后续行覆盖。我建议使用两种方法中的一种,第一种方法是最简单的方法,但第二种方法更好,因为你只需要为每个对象做一次free()。
第一个只是对add()函数的一次更改:
temp->data = malloc(strlen(line)+1);
strcpy(temp->data, line);
现在,当你想释放链表中的一个对象时,你必须首先调用free()数据然后free()对象本身。
但是,您可以稍微更改结构,然后您可以一次性分配整个对象:
typedef struct node {
struct node *next;
char data[0];
} node;
然后你的add()函数看起来像这样:
void add(char *line) {
node *temp = malloc(sizeof(node)+strlen(line)+1);
strcpy(temp->data, line);
temp->next = NULL;
current = start;
if(start == NULL) {
start = temp;
} else {
while(current->next != NULL) {
current = current->next;
}
current->next = temp;
}
}
请注意,您当然应该在生产代码中的每个malloc()之后执行错误检查。当你完成一个对象时,一个free()足以释放整个结构。
编辑:"数组长度0" feature是一个GCC特定的扩展,正如@crashmstr在评论中所指出的那样。如果使用数组长度为1,则它应该适用于任何编译器:
typedef struct node {
struct node *next;
char data[1];
} node;
由于在这种情况下已经分配了一个额外的字节,因此add()函数中的malloc()调用将变为:
node *temp = malloc(sizeof(node)+strlen(line)+1-1);
(当然+ 1-1可以省略,但它只是为了表明我们仍然需要空终止器,但是sizeof中已经包含了一个额外的字节)。