鱼C论坛

 找回密码
 立即注册
查看: 1594|回复: 14

[已解决]求帮助,非常着急,大佬们,有关链表与文件的

[复制链接]
发表于 2018-9-6 19:38:35 | 显示全部楼层 |阅读模式
66鱼币
[
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Student
{
        char name[20];
        long long int numb;
        struct Student * pNext;
 } ;
 struct Student_1
{
        char name[20];
        long long int numb;
 } ;
int n;

struct Student * create()
{
        FILE * fp;
        if((fp=fopen("student","wb"))==NULL)
        {
                printf("cannot open file\n");
                exit(0);
        }
        struct Student *head=NULL,*pEnd,*pNew,*p;
        n=0;
        char ch;
        pEnd=pNew=(struct Student*)malloc(sizeof(struct Student));
        do
        {
           printf("请输入学生姓名:\n");
           scanf("%s",pNew->name);
           getchar();
           printf("请输入学生学号:\n");
           scanf("%lld",&pNew->numb );
           getchar();
           n++;
           if(n==1)
           {
                pNew->pNext=head;
                head=pNew;
           }
           else
           {
                pNew->pNext=NULL;
                pEnd->pNext=pNew;
                pEnd=pNew;
            }   
            
            printf("是否继续录入(y/n):\n");
            ch=getchar();
            getchar();
            if(ch=='y')
               pNew=(struct Student*)malloc(sizeof(struct Student));
    }while(ch=='y');
    p=head;
    while(p!=NULL)
    {  
            if(fwrite(p,sizeof(struct Student_1),1,fp)!=1)
            {
                    printf("录入出错!\n");
                }
                p=p->pNext;
        }
        fclose(fp);        
        return head;
}
void print(struct Student* head)
{
        struct Student *p;
        p=head;
        printf("姓名\t\t学号\n");
        while(p!=NULL)
        {
                printf("%s\t\t%lld\n",p->name,p->numb);
                p=p->pNext;
        }
}



int main()
{
        struct Student* head;
        head=create();
        system("cls");
        print(head);
        return 0;
}
这是用c写的用链表形式将数据以二进制形式写入文件;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Student
{
        char name[20];
        long long int numb;
        struct Student * pNext;
 } ;
 struct Student_1
{
        char name[20];
        long long int numb;
 } ;
int n;

struct Student * fprint()
{
        FILE *fp;
        struct Student *head=NULL,*pnew,*pend;
        if((fp=fopen("student","rb"))==NULL)
        {
                printf("不能打开文件!");
                exit(0); 
         } 
         n=0;
         while(!feof(fp))
         {
                 n++;     
                 pnew=(struct Student*)malloc(sizeof(struct Student));
                 fread(pnew,sizeof(struct Student_1),1,fp);
                 if(n==1)
                 {
                         pnew->pNext=head; 
                         head=pnew;
                         pend=pnew;
                 }
                 else
                 {
                         pend->pNext=pnew;
                         pend=pnew;
                         pnew->pNext=NULL;
                 }
         }
         return head;
}



void print(struct Student* head)
{
        struct Student *p;
        p=head;
        printf("姓名\t\t学号\n");
        while(p!=NULL)
        {
                printf("%s\t\t%lld\n",p->name,p->numb);
                p=p->pNext;
         
        }
}



int main()
{
        struct Student* head;
        head=fprint();
        
        print(head);
        return 0;
}
这是对应上面的,可以将数据从文件中读取,但是问题是我录入一组数据,输出两组数据(第二组是乱码),每一次输出都比输入数据多一组?这问题出在哪里了?附上图
最佳答案
2018-9-6 19:38:36
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Student
{
        char name[20];
        long long int numb;
        struct Student *pNext;
};
struct Student_1
{
        char name[20];
        long long int numb;
};
int n;

struct Student *fprint()
{
        FILE *fp;
        struct Student *head = NULL, *pnew, *pend;
        if((fp = fopen("student", "rb")) == NULL)
        {
                printf("不能打开文件!");
                exit(0);
        }

        n = 0;
        /*while(!feof(fp))
        {
                n++;
                pnew = (struct Student*)malloc(sizeof(struct Student));
                fread(pnew, sizeof(struct Student_1), 1, fp);
                if(n == 1)
                {
                        pnew->pNext = head;
                        head = pnew;
                        pend = pnew;
                }
                else
                {
                        pend->pNext = pnew;
                        pend = pnew;
                        pnew->pNext = NULL;
                }
        }*/
        while(1)
        {
                n++;
                pnew = (struct Student*)malloc(sizeof(struct Student));
                fread(pnew, sizeof(struct Student_1), 1, fp);
                if(feof(fp))
                {
                        free(pnew);
                        break;
                }

                if(n == 1)
                {
                        pnew->pNext = head;
                        head = pnew;
                        pend = pnew;
                }
                else
                {
                        pend->pNext = pnew;
                        pend = pnew;
                        pnew->pNext = NULL;
                }
        }

        return head;
}

void print(struct Student* head)
{
        struct Student *p;
        p = head;
        printf("姓名\t\t学号\n");
        while(p != NULL)
        {
                printf("%s\t\t%lld\n", p->name, p->numb);
                p = p->pNext;

        }
}

int main(void)
{
        struct Student* head;
        head = fprint();
        print(head);
        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-9-6 19:38:36 | 显示全部楼层    本楼为最佳答案   
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Student
{
        char name[20];
        long long int numb;
        struct Student *pNext;
};
struct Student_1
{
        char name[20];
        long long int numb;
};
int n;

struct Student *fprint()
{
        FILE *fp;
        struct Student *head = NULL, *pnew, *pend;
        if((fp = fopen("student", "rb")) == NULL)
        {
                printf("不能打开文件!");
                exit(0);
        }

        n = 0;
        /*while(!feof(fp))
        {
                n++;
                pnew = (struct Student*)malloc(sizeof(struct Student));
                fread(pnew, sizeof(struct Student_1), 1, fp);
                if(n == 1)
                {
                        pnew->pNext = head;
                        head = pnew;
                        pend = pnew;
                }
                else
                {
                        pend->pNext = pnew;
                        pend = pnew;
                        pnew->pNext = NULL;
                }
        }*/
        while(1)
        {
                n++;
                pnew = (struct Student*)malloc(sizeof(struct Student));
                fread(pnew, sizeof(struct Student_1), 1, fp);
                if(feof(fp))
                {
                        free(pnew);
                        break;
                }

                if(n == 1)
                {
                        pnew->pNext = head;
                        head = pnew;
                        pend = pnew;
                }
                else
                {
                        pend->pNext = pnew;
                        pend = pnew;
                        pnew->pNext = NULL;
                }
        }

        return head;
}

void print(struct Student* head)
{
        struct Student *p;
        p = head;
        printf("姓名\t\t学号\n");
        while(p != NULL)
        {
                printf("%s\t\t%lld\n", p->name, p->numb);
                p = p->pNext;

        }
}

int main(void)
{
        struct Student* head;
        head = fprint();
        print(head);
        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-9-6 19:40:15 | 显示全部楼层
1.png 2.png 3.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-9-6 19:58:00 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-9-6 21:35:30 | 显示全部楼层
本帖最后由 理想小青年 于 2018-9-6 21:37 编辑

大体判断一下,错误原因,结构体大小不一样,Student是40字节大小,Student_1是32字节大小,所以
1、pnew = (struct Student*)malloc(sizeof(struct Student));
     fread(pnew, sizeof(struct Student_1), 1, fp);
上面两句是错误的,读取块大小是32字节,应该是40个字节。
两个结构体大小不一样, 应该这样写:
(1)fread(pnew, sizeof(struct Student), 1, fp);
(2)fwrite(p,sizeof(struct Student),1,fp);
2、打开文件应该是 "rb+","wb+"  把加号写上。
3、 养成关闭文件习惯fclose();
然后在尝试看一看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-9-6 21:43:36 From FishC Mobile | 显示全部楼层
理想小青年 发表于 2018-9-6 21:35
大体判断一下,错误原因,结构体大小不一样,Student是40字节大小,Student_1是32字节大小,所以
1、pnew  ...

结构体不一样是因为我要往文件储存时不想把指针存进去,因为这样完全没必要,到时候还是要给指针赋值的,之前我就只定义了一个结构体,但是问题依然还有,关闭文件会修改的,谢谢您(*°°)=3
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-9-6 21:47:32 | 显示全部楼层
...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-9-6 23:29:22 | 显示全部楼层

666,厉害,PS:不过我想知道我的为什么不可以呢?怎么会多出一组呢?不是到文件尾就结束循环了吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-9-6 23:49:05 | 显示全部楼层
易晓外 发表于 2018-9-6 23:29
666,厉害,PS:不过我想知道我的为什么不可以呢?怎么会多出一组呢?不是到文件尾就结束循环了吗?

自己百度 feof函数
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-9-7 13:23:08 | 显示全部楼层
易晓外 发表于 2018-9-6 23:29
666,厉害,PS:不过我想知道我的为什么不可以呢?怎么会多出一组呢?不是到文件尾就结束循环了吗?

*head = NULL
不是很清楚为什么哥哥要这样写
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-9-7 13:26:16 | 显示全部楼层
本帖最后由 claws0n 于 2018-9-7 13:29 编辑
人造人 发表于 2018-9-6 23:49
自己百度 feof函数


写入
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Student
{
    char name[20];
    long long int numb;
    struct Student* pNext;
} ;

struct Student_1
{
    char name[20];
    long long int numb;
} ;

struct Student * create()
{
    FILE * fp;
    if((fp=fopen("student.txt","wb")) == NULL)
    {
            printf("cannot open file\n");
            exit(0);
    }
    
    struct Student *head, *pNew, *p;
        head->pNext = NULL;
    char ch;
    
    pNew = (struct Student*)malloc(sizeof(struct Student));
    
    p = head;        //索引指针 
    while( p->pNext )                //尾插法 
        p = p->pNext; 
    do
    {
        printf("请输入学生姓名:\n");
        scanf("%s", pNew->name);
        getchar();
        printf("请输入学生学号:\n");
        scanf("%lld", &pNew->numb);
        getchar();
                
        p->pNext = pNew;
        pNew->pNext = NULL;
        p = p->pNext;
        
        printf("是否继续录入(y/n):\n");
        ch = getchar();
        getchar();
        if(ch == 'y'|| ch == 'Y') //把大写也纳入 
           pNew = (struct Student*)malloc(sizeof(struct Student));
           
    }while(ch == 'y'|| ch == 'Y'); //把大写也纳入 
    
    p = head->pNext;
    while( p )
    {  
        if(fwrite(p, sizeof(struct Student_1), 1, fp) != 1)
        {
            printf("录入出错!\n");
        }
        p = p->pNext;
    }
    fclose(fp);
    return head;
}

void print(struct Student* head)
{
    struct Student *p;
    p = head->pNext;
    printf("姓名\t\t学号\n");
    while( p )
    {
        printf("%s\t\t%lld\n", p->name, p->numb);
        p = p->pNext;
    }
}


int main()
{
    struct Student* head;
    head = create();
    system("cls");
    print(head);
    return 0;
}
读取
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Student
{
    char name[20];
    long long int numb;
    struct Student * pNext;
} ;

struct Student_1
{
    char name[20];
    long long int numb;
} ;


struct Student * fprint()
{
FILE *fp;
struct Student *head, *pNew, *p;
        
if((fp = fopen("student.txt","rb")) == NULL)
{
        printf("不能打开文件!");
        exit(0); 
}
        
head->pNext = NULL; 
p = head;
        
while(!feof(fp))
{
        pNew = (struct Student*)malloc(sizeof(struct Student));
        fread(pNew, sizeof(struct Student_1), 1, fp);
                
        p->pNext = pNew;
        pNew->pNext = NULL;
        p = p->pNext;
}
return head;
}



void print(struct Student* head)
{
    struct Student *p;
    p = head->pNext;
    printf("姓名\t\t学号\n");
    while( p->pNext )
    {
        printf("%s\t\t%lld\n", p->name, p->numb);
        p = p->pNext;
    }
}

int main()
{
    struct Student* head;
    head = fprint();
    printf("reading...\n");
    print(head);
    return 0;
}
*head = NULL 的问题吧?虽然浪费了一个空间,但这样写不是更好吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-9-7 17:19:55 | 显示全部楼层
claws0n 发表于 2018-9-7 13:26
写入读取
*head = NULL 的问题吧?虽然浪费了一个空间,但这样写不是更好吗?

什么?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-9-7 18:30:41 | 显示全部楼层

问题应该是出至于头指针。我把插入的方法稍微改了一下,就不会有问题了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-9-7 21:08:10 | 显示全部楼层
claws0n 发表于 2018-9-7 18:30
问题应该是出至于头指针。我把插入的方法稍微改了一下,就不会有问题了

1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-9-7 21:27:19 | 显示全部楼层
“C”语言的“feof()”函数和数据库中“eof()”函数的运作是完全不同的。数据库中“eof()”函数读取当前指针的位置,“C”语言的“feof()”函数返回的是最后一次“读操作的内容”。多年来把“位置和内容”相混,从而造成了对这一概念的似是而非。

那么,位置和内容到底有何不同呢?举个简单的例子,比如有人说“你走到火车的最后一节车箱”这就是位置。而如果说“请你一直向后走,摸到铁轨结束”这就是内容。也就是说用内容来判断会“多走一节”。这就是完全依赖于“while(!feof(FP)){...}”进行文件复制时,目标文档总会比源文档“多出一些”的原因。
这是错误原因!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-30 08:57

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表