Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么我的;“打印”;函数只读取最后一个元素和垃圾,然后停止响应?_C_Linked List - Fatal编程技术网

C 为什么我的;“打印”;函数只读取最后一个元素和垃圾,然后停止响应?

C 为什么我的;“打印”;函数只读取最后一个元素和垃圾,然后停止响应?,c,linked-list,C,Linked List,看起来它打印了最后一行和下一行(这是垃圾)。我想问题出在read函数中 这是正确的 原因如下: input file name: input.txt.txt student01 1 95.000000 student03 3 90.000000 student05 5 86.000000 student07 7 83.000000 student09 9 98.000000 s

看起来它打印了最后一行和下一行(这是垃圾)。我想问题出在read函数中

这是正确的

原因如下:

input file name: input.txt.txt
student01       1       95.000000
student03       3       90.000000
student05       5       86.000000
student07       7       83.000000
student09       9       98.000000
student10       10      93.000000
student08       8       92.000000
student06       6       96.000000
student04       4       93.000000
student02       2       88.000000

ID=2
Name=student02
Marks=88.000000

ID=11552328
░ame=P
Marks=13640062821560266000000000000000000.000000


Process returned -1073741819 (0xC0000005)   execution time : 6.737 s
Press any key to continue.
在这个循环中,您总是读取列表第一个元素中的所有数据。 您分配了一些新节点,但从未向其分配任何内容。 通过将
NULL
赋值给
list->next->next
,您甚至不会终止列表

这导致了各种问题:

  • 您可以为每个迭代分配内存,但只能通过
    list->next
    访问最后一个迭代。所有其他内存块都将丢失
  • 您有一个未终止的列表,当您在打印期间尝试遍历所有节点时,该列表会导致未定义的行为
  • 您将所有数据读取到一个位置,这意味着您丢失了文件中除最后一行以外的所有数据
要解决此问题,您需要如下更改:

    while(fscanf(fp, "%s %d %f", list->name, &list->id, &list->marks) == 3)
    {
        printf("%s \t%d \t%f\n", list->name,list->id,list->marks);//check
        list->next=(node*)malloc(sizeof(node));//create next node
    }
除此之外:

  • 显然,您没有使用
    main
    可能具有
    void
    返回类型的嵌入式系统。对于所有托管环境,它必须返回
    int
  • 为什么定义标准宏
    NULL
    ?您应该包括定义它的C标准标题。除此之外,
    NULL
    是一个指针值。为什么使用整数类型

以下建议代码:

    while(fscanf(fp, "%s %d %f", list->name, &list->id, &list->marks) == 3)
    {
        printf("%s \t%d \t%f\n", list->name,list->id,list->marks);//check
        list->next=(node*)malloc(sizeof(node));//create next node
        if (list->next != NULL)
        {
            list = list->next; // Advance to new node
            list->next = NULL; // Terminate list at this node (until a new one is added)
        }
        else
        {
          // error handling
          exit(1);
        }
    }
  • 干净地编译
  • 执行大多数错误检查
  • 实际生成
    struct student
  • 记录包含每个头文件的原因
  • 消除了大多数“神奇”数字
  • 正确初始化
    next
    字段
  • 无法将分配的内存区域传递到
    free()
  • head
    的地址正确地传递给
    read()
    函数,因此当列表为空时,可以使用指向第一个
    节点的指针更新
    head
    的内容
  • 指针正确初始化为NULL
  • 将每个新节点正确链接到上一个节点
  • 现在,拟议的守则:

        while(fscanf(fp, "%s %d %f", list->name, &list->id, &list->marks) == 3)
        {
            printf("%s \t%d \t%f\n", list->name,list->id,list->marks);//check
            list->next=(node*)malloc(sizeof(node));//create next node
            if (list->next != NULL)
            {
                list = list->next; // Advance to new node
                list->next = NULL; // Terminate list at this node (until a new one is added)
            }
            else
            {
              // error handling
              exit(1);
            }
        }
    
    #包括//文件、fopen、fclose、scanf()、fscanf()、printf()
    #包括//malloc()、free()、exit()、exit_失败
    #include//memcpy()
    #定义最大名称长度20
    #定义最大文件名长度30
    结构学生
    {
    int-id;
    字符名[MAX_name_LEN];
    浮标;
    结构学生*下一步;
    };
    typedef结构学生节点;
    无效读取回波记录(节点**p);
    void创建(节点*p);
    整数计数(节点*p);
    作废打印(节点*p);
    内部主(空)
    {
    node*head=NULL;
    读取回音记录(&head);
    printf(“\n”);
    打印头;
    }
    作废读取\回显\记录(节点**列表)
    {
    文件*fp;
    字符文件名[MAX_filename_LEN];
    printf(“输入文件名:”);
    scanf(“%29s”,文件名);
    fp=fopen(文件名,“r”);
    如果(fp==NULL)
    {
    perror(“fopen失败”);
    退出(退出失败);
    }
    节点*当前=*列表;
    节点*prior=*列表;
    节点工作空间;
    workspace.next=NULL;
    而(fscanf(fp,“%s%d%f”,workspace.name,&workspace.id,&workspace.marks)==3)
    {
    printf(“%s\t%d\t%f\n”,workspace.name,workspace.id,workspace.marks);//检查
    if(!(current=malloc(sizeof(node)))//创建下一个节点
    {
    perror(“malloc失败”);
    fclose(fp);
    退出(退出失败);
    }
    memcpy(当前和工作空间,大小(节点));
    *上一个->下一个=当前;
    先验=当前;
    }
    fclose(fp);
    返回;
    }
    作废打印(节点*列表)
    {
    节点*当前=列表;
    如果(!当前)
    {
    printf(“%s\n”,“列表为空”);
    返回;
    }
    while(当前->下一步)
    {
    printf(“ID=%d\n”,当前->ID);
    printf(“名称=%s\n”,当前->名称);
    printf(“标记=%f\n”,当前->标记);
    printf(“\n”);
    当前=当前->下一步;
    } 
    }
    
    我没有将数据分配给节点,你能解释一下吗?你分配了一个指针
    list->next
    ,但从未给分配内存的任何字段分配任何值。我不确定这里有什么不清楚的地方…或者这样说:你认为,你在哪里使用那个新节点?对不起,我真的是个新手。我想你的意思是我总是读取文件并在第一个节点分配它,而不是分配到下一个节点?是的,正确。您没有切换到新的/下一个节点。关于:
    #定义NULL 0
    这不是有效的NULL定义。有效的定义是
    #define NULL void*0
    发布的代码不编译!它缺少
    printf()
    fopen()
    scanf()
    fscanf()
    的原型,以及NULL和
    FILE
    fclose()
    所有这些都可以通过包含头文件来更正:
    stdio.h
    关于语句:
    void main()
    main()
    只有两个有效的签名:
    int main(void)
    int main(int argc,char*argv[])
    注意,它们的返回类型都是
    int
    ,而不是
    void
    函数名
    read()
    是众所周知的函数。在
    struct student
    的定义中,试图用“自产”函数替换C库函数的定义是一种糟糕的编程实践,此字段:
    struct student*next
    无效,因为它缺少所需的尾随半色
    
    
    #include <stdlib.h>   // FILE, fopen, fclose, scanf(), fscanf(), printf()
    #include <stdio.h>    // malloc(), free(), exit(), EXIT_FAILURE
    #include <string.h>   // memcpy()
    
    #define MAX_NAME_LEN 20
    #define MAX_FILENAME_LEN 30
    
    struct student
    {
        int id;
        char name[ MAX_NAME_LEN ];
        float marks;
        struct student *next;
    };
    typedef struct student node;
    
    
    void read_echo_records  (node **p);
    void create(node *p);
    int  count (node *p);
    void print (node *p);
    
    
    int main( void )
    {
        node *head = NULL;
    
        read_echo_records( &head);
        printf("\n");
        print(head);
    }
    
    
    void read_echo_records(node **list)
    {
        FILE *fp;
        char filename[ MAX_FILENAME_LEN ];
        printf("input file name: ");
        scanf("%29s",filename);
    
        fp = fopen( filename, "r" );
        if( fp == NULL )
        {
            perror( "fopen failed" );
            exit( EXIT_FAILURE );
        }
    
        node *current = *list;
        node *prior   = *list;
        node workspace;
        workspace.next = NULL;
    
        while(fscanf(fp, "%s %d %f", workspace.name, &workspace.id, &workspace.marks) == 3)
        {
            printf("%s \t%d \t%f\n", workspace.name, workspace.id, workspace.marks);//check
    
            if( ! (current = malloc(sizeof(node))) )//create next node
            {
                perror( "malloc failed" );
                fclose( fp );
                exit( EXIT_FAILURE );
            }
    
            memcpy( current, &workspace, sizeof( node ) );
            *prior->next = current;
            prior = current;
        }
        fclose(fp);
        return;
    }
    
    
    void print(node*list)
    {
        node *current = list;
        if( ! current )
        {
            printf( "%s\n", "list is empty" );
            return;
        }
    
        while( current->next )
        {
           printf( "ID=%d\n", current->id );
           printf( "Name=%s\n", current->name );
           printf( "Marks=%f\n", current->marks );
           printf( "\n");
           current = current->next;
        } 
    }