将文本文件中的数字推入 link 列表
Pushing numbers from a text file into a link list
我正在尝试将文本文件中的数字推送到链接列表中,该列表可能在多行中包含多个数字。我的输出一团糟,只多次打印 -47。我的主要疑问是如何从文件中读取 2 位数字,尽管我当前的代码甚至没有读取任何数字。
我的代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct linklist
{
int data;
struct linklist *addr;
}ll;
void push(ll **h,int val);
void display(ll **h);
void main()
{
FILE *fp;
fp=fopen("re.txt","r");
char c;
ll *head=NULL;
while(c=fgetc(fp)!=EOF)
{
if(c==' ' || c=='\n')
{
continue;
}
else
{
int temp=c-'0';
printf("Temp = %d",temp);
push(&head,temp);
}
}
printf("check");
display(&head);
fclose(fp);
}
void push(ll **h,int val)
{
if(*h==NULL)
{
ll *temp=(ll*)malloc(sizeof(ll));
temp->data=val;
temp->addr=NULL;
*h=temp;
}
else
{
ll *current = *h;
while(current->addr!=NULL)
current=current->addr;
current->addr=(ll*)malloc(sizeof(ll));
current->addr->data=val;
current->addr->addr=NULL;
}
}
void display(ll **h)
{
ll *current=*h;
while(current->addr!=NULL)
{
printf("%d\t",current->data);
current=current->addr;
}
}
编辑:
re.txt 文件如下所示:
4
2 1 8 19
6 11 50 89
21 22 47
25 35
使用 fscanf
为您完成工作。
你想要这个:
int main()
{
FILE* fp;
fp = fopen("re.txt", "r");
if (fp == NULL)
{
printf("Can't open file\n");
return 1;
}
char c;
ll* head = NULL;
int temp;
while (fscanf(fp, "%d", &temp) != EOF)
{
printf("Temp = %d\n", temp);
push(&head, temp);
}
printf("check");
display(&head);
fclose(fp);
}
虽然还有改进的空间。
对于初学者来说,while 循环中的条件
while(c=fgetc(fp)!=EOF)
不正确。相当于下面的条件
while( c = ( fgetc(fp) != EOF ) )
因此,如果 fgetc( fp )
不等于 EOF
,则表达式 fgetc( fp ) != EOF
的计算结果为 1
,变量 c
将获得此值 1
.
while 循环至少应该像
while( ( c = fgetc(fp) ) != EOF )
变量 c
的类型应该是 int
.
int c;
否则循环可能是无限的,因为类型 char
可以表现为类型 unsigned char
(取决于编译器的选项)并且变量 c
永远不会相等到 EOF
.
的有符号值
但是无论如何这个循环都是不正确的,因为函数 fgetc
也读取白色 space 字符,而您需要读取整数。
所以把循环改成
int temp;
while ( fscanf( fp, "%d", &temp ) == 1 )
{
push( &head, temp );
}
函数push
也可以看起来更简单。并且它可以向调用者发出新节点的内存是否已成功分配的信号,否则该函数可以在内存分配失败的情况下调用未定义的行为。例如
int push( ll **h, int val )
{
ll *temp = malloc( sizeof( ll ) );
int success = temp != NULL;
if ( success )
{
temp->data = val;
temp->addr = NULL;
while ( *h != NULL ) h = &( *h )->addr;
*h = temp;
}
return success;
}
当传递给头节点的指针等于NULL
时,函数display
可以调用未定义的行为。如果列表只包含一个节点,该函数将不输出任何内容。
函数可以这样声明
void display( ll **h )
{
for ( ll *current = *h; current != NULL; current = current->addr )
{
printf("%d\t",current->data);
}
}
我正在尝试将文本文件中的数字推送到链接列表中,该列表可能在多行中包含多个数字。我的输出一团糟,只多次打印 -47。我的主要疑问是如何从文件中读取 2 位数字,尽管我当前的代码甚至没有读取任何数字。
我的代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct linklist
{
int data;
struct linklist *addr;
}ll;
void push(ll **h,int val);
void display(ll **h);
void main()
{
FILE *fp;
fp=fopen("re.txt","r");
char c;
ll *head=NULL;
while(c=fgetc(fp)!=EOF)
{
if(c==' ' || c=='\n')
{
continue;
}
else
{
int temp=c-'0';
printf("Temp = %d",temp);
push(&head,temp);
}
}
printf("check");
display(&head);
fclose(fp);
}
void push(ll **h,int val)
{
if(*h==NULL)
{
ll *temp=(ll*)malloc(sizeof(ll));
temp->data=val;
temp->addr=NULL;
*h=temp;
}
else
{
ll *current = *h;
while(current->addr!=NULL)
current=current->addr;
current->addr=(ll*)malloc(sizeof(ll));
current->addr->data=val;
current->addr->addr=NULL;
}
}
void display(ll **h)
{
ll *current=*h;
while(current->addr!=NULL)
{
printf("%d\t",current->data);
current=current->addr;
}
}
编辑:
re.txt 文件如下所示:
4
2 1 8 19
6 11 50 89
21 22 47
25 35
使用 fscanf
为您完成工作。
你想要这个:
int main()
{
FILE* fp;
fp = fopen("re.txt", "r");
if (fp == NULL)
{
printf("Can't open file\n");
return 1;
}
char c;
ll* head = NULL;
int temp;
while (fscanf(fp, "%d", &temp) != EOF)
{
printf("Temp = %d\n", temp);
push(&head, temp);
}
printf("check");
display(&head);
fclose(fp);
}
虽然还有改进的空间。
对于初学者来说,while 循环中的条件
while(c=fgetc(fp)!=EOF)
不正确。相当于下面的条件
while( c = ( fgetc(fp) != EOF ) )
因此,如果 fgetc( fp )
不等于 EOF
,则表达式 fgetc( fp ) != EOF
的计算结果为 1
,变量 c
将获得此值 1
.
while 循环至少应该像
while( ( c = fgetc(fp) ) != EOF )
变量 c
的类型应该是 int
.
int c;
否则循环可能是无限的,因为类型 char
可以表现为类型 unsigned char
(取决于编译器的选项)并且变量 c
永远不会相等到 EOF
.
但是无论如何这个循环都是不正确的,因为函数 fgetc
也读取白色 space 字符,而您需要读取整数。
所以把循环改成
int temp;
while ( fscanf( fp, "%d", &temp ) == 1 )
{
push( &head, temp );
}
函数push
也可以看起来更简单。并且它可以向调用者发出新节点的内存是否已成功分配的信号,否则该函数可以在内存分配失败的情况下调用未定义的行为。例如
int push( ll **h, int val )
{
ll *temp = malloc( sizeof( ll ) );
int success = temp != NULL;
if ( success )
{
temp->data = val;
temp->addr = NULL;
while ( *h != NULL ) h = &( *h )->addr;
*h = temp;
}
return success;
}
当传递给头节点的指针等于NULL
时,函数display
可以调用未定义的行为。如果列表只包含一个节点,该函数将不输出任何内容。
函数可以这样声明
void display( ll **h )
{
for ( ll *current = *h; current != NULL; current = current->addr )
{
printf("%d\t",current->data);
}
}