将文本文件中的数字推入 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);
    }
}