将数字文件读入链表
Reading a file of digits into a linked list
我没有收到任何错误;该代码有效,但它只显示第一个元素,不显示其他元素。我想用链表显示文件中的所有数字。我的错误是什么?
numbers.txt
中的数字:
9 2 3
4 2 3
1 2 9
2 4 8
7 5 9
2 4 7
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
struct NUMBERS{
int katsayi;
int taban;
int us;
NUMBERS *next;
};
int main(){
NUMBERS *temp=NULL;
NUMBERS *list=NULL; // to keep first element
NUMBERS *head=NULL; // temp for the first element
FILE *fp=fopen("numbers.txt","r+");
while(!feof(fp)){
temp=(NUMBERS*)malloc(sizeof(NUMBERS));
fscanf(fp,"%d %d %d",&temp->katsayi,&temp->taban,&temp->us);
temp->next=NULL;
if(list==NULL){
list=temp;
}
else{
head=list;
while(head->next!=NULL){
head=head->next;
}
head=temp;
}
}
head=list;
while(head!=NULL){
printf("%d %d %d",head->katsayi,head->taban,head->us);
head=head->next;
}
return 0;
}
这里有几个问题:
while(!feof(fp)){
是 wrong 因为它告诉我们什么时候我们已经读过了文件的末尾,而不是当我们在最后一行时(详见 link ).您可以检查是否fscanf != EOF
的return。我假设 post 中的空白行是格式错误,但如果不是,您可以使用 fscanf
的 return 值来确保所有 3 位数字都匹配并跳过它们不存在的任何行。
- 代码不应编译,因为
NUMBERS
尚未 typedef
。不需要全部大写,这通常是为常量保留的。
- No need 将
malloc
的结果转换为 C.
插入新节点的代码:
head=list;
while(head->next!=NULL){
head=head->next;
}
head=temp;
没有多大意义。遍历列表后,head
简单地设置为 temp
,取消遍历。在任何情况下,我们都不应该仅仅为了添加一个节点而遍历整个列表。解决方案是使用 tail
节点,它始终指向列表中的最后一个元素。
- 代码泄漏内存。
free
每 malloc
.
- 打开文件时检查错误并正常退出。
- 考虑一个
LinkedList
结构,它封装了 head/tail 指针并具有相应的 insertion/removal/traversal/free 函数。 main
也应该分解为函数(reader 的练习)。
这是一个初始重写:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Numbers {
int katsayi;
int taban;
int us;
struct Numbers *next;
} Numbers;
int main() {
Numbers *temp = NULL;
Numbers *list = NULL;
Numbers *tail = NULL;
Numbers dummy;
char file[] = "numbers.txt";
FILE *fp = fopen(file, "r");
if (!fp) {
fprintf(stderr, "%s %d: could not open %s \n",
__FILE__, __LINE__, file);
exit(1);
}
while (fscanf(fp, "%d %d %d",
&dummy.katsayi, &dummy.taban, &dummy.us) != EOF) {
temp = malloc(sizeof(*temp));
memcpy(temp, &dummy, sizeof(*temp));
temp->next = NULL;
if (list) {
tail->next = temp;
}
else {
list = temp;
}
tail = temp;
}
for (temp = list; temp; temp = temp->next) {
printf("%d %d %d\n",
temp->katsayi, temp->taban, temp->us);
}
for (temp = list; temp;) {
Numbers *prev = temp;
temp = temp->next;
free(prev);
}
return 0;
}
输出:
9 2 3
4 2 3
1 2 9
2 4 8
7 5 9
2 4 7
我没有收到任何错误;该代码有效,但它只显示第一个元素,不显示其他元素。我想用链表显示文件中的所有数字。我的错误是什么?
numbers.txt
中的数字:
9 2 3
4 2 3
1 2 9
2 4 8
7 5 9
2 4 7
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
struct NUMBERS{
int katsayi;
int taban;
int us;
NUMBERS *next;
};
int main(){
NUMBERS *temp=NULL;
NUMBERS *list=NULL; // to keep first element
NUMBERS *head=NULL; // temp for the first element
FILE *fp=fopen("numbers.txt","r+");
while(!feof(fp)){
temp=(NUMBERS*)malloc(sizeof(NUMBERS));
fscanf(fp,"%d %d %d",&temp->katsayi,&temp->taban,&temp->us);
temp->next=NULL;
if(list==NULL){
list=temp;
}
else{
head=list;
while(head->next!=NULL){
head=head->next;
}
head=temp;
}
}
head=list;
while(head!=NULL){
printf("%d %d %d",head->katsayi,head->taban,head->us);
head=head->next;
}
return 0;
}
这里有几个问题:
while(!feof(fp)){
是 wrong 因为它告诉我们什么时候我们已经读过了文件的末尾,而不是当我们在最后一行时(详见 link ).您可以检查是否fscanf != EOF
的return。我假设 post 中的空白行是格式错误,但如果不是,您可以使用fscanf
的 return 值来确保所有 3 位数字都匹配并跳过它们不存在的任何行。- 代码不应编译,因为
NUMBERS
尚未typedef
。不需要全部大写,这通常是为常量保留的。 - No need 将
malloc
的结果转换为 C. 插入新节点的代码:
head=list; while(head->next!=NULL){ head=head->next; } head=temp;
没有多大意义。遍历列表后,
head
简单地设置为temp
,取消遍历。在任何情况下,我们都不应该仅仅为了添加一个节点而遍历整个列表。解决方案是使用tail
节点,它始终指向列表中的最后一个元素。- 代码泄漏内存。
free
每malloc
. - 打开文件时检查错误并正常退出。
- 考虑一个
LinkedList
结构,它封装了 head/tail 指针并具有相应的 insertion/removal/traversal/free 函数。main
也应该分解为函数(reader 的练习)。
这是一个初始重写:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Numbers {
int katsayi;
int taban;
int us;
struct Numbers *next;
} Numbers;
int main() {
Numbers *temp = NULL;
Numbers *list = NULL;
Numbers *tail = NULL;
Numbers dummy;
char file[] = "numbers.txt";
FILE *fp = fopen(file, "r");
if (!fp) {
fprintf(stderr, "%s %d: could not open %s \n",
__FILE__, __LINE__, file);
exit(1);
}
while (fscanf(fp, "%d %d %d",
&dummy.katsayi, &dummy.taban, &dummy.us) != EOF) {
temp = malloc(sizeof(*temp));
memcpy(temp, &dummy, sizeof(*temp));
temp->next = NULL;
if (list) {
tail->next = temp;
}
else {
list = temp;
}
tail = temp;
}
for (temp = list; temp; temp = temp->next) {
printf("%d %d %d\n",
temp->katsayi, temp->taban, temp->us);
}
for (temp = list; temp;) {
Numbers *prev = temp;
temp = temp->next;
free(prev);
}
return 0;
}
输出:
9 2 3
4 2 3
1 2 9
2 4 8
7 5 9
2 4 7