易晓外 发表于 2018-9-6 19:38:35

求帮助,非常着急,大佬们,有关链表与文件的

[#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Student
{
        char name;
        long long int numb;
        struct Student * pNext;
} ;
struct Student_1
{
        char name;
        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;
        long long int numb;
        struct Student * pNext;
} ;
struct Student_1
{
        char name;
        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;
        long long int numb;
        struct Student *pNext;
};
struct Student_1
{
        char name;
        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;
}

易晓外 发表于 2018-9-6 19:40:15

claws0n 发表于 2018-9-6 19:58:00

@人造人

理想小青年 发表于 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();
然后在尝试看一看

易晓外 发表于 2018-9-6 21:43:36

理想小青年 发表于 2018-9-6 21:35
大体判断一下,错误原因,结构体大小不一样,Student是40字节大小,Student_1是32字节大小,所以
1、pnew...

结构体不一样是因为我要往文件储存时不想把指针存进去,因为这样完全没必要,到时候还是要给指针赋值的,之前我就只定义了一个结构体,但是问题依然还有{:10_247:},关闭文件会修改的,谢谢您(*°°)=3

钱闻韬 发表于 2018-9-6 21:47:32

...

易晓外 发表于 2018-9-6 23:29:22

人造人 发表于 2018-9-6 23:23


666,厉害,PS:不过我想知道我的为什么不可以呢?怎么会多出一组呢?不是到文件尾就结束循环了吗?

人造人 发表于 2018-9-6 23:49:05

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

自己百度 feof函数

claws0n 发表于 2018-9-7 13:23:08

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

*head = NULL
不是很清楚为什么哥哥要这样写

claws0n 发表于 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;
    long long int numb;
    struct Student* pNext;
} ;

struct Student_1
{
    char name;
    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;
    long long int numb;
    struct Student * pNext;
} ;

struct Student_1
{
    char name;
    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 的问题吧?虽然浪费了一个空间,但这样写不是更好吗?

人造人 发表于 2018-9-7 17:19:55

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

什么?

claws0n 发表于 2018-9-7 18:30:41

人造人 发表于 2018-9-7 17:19
什么?

问题应该是出至于头指针。我把插入的方法稍微改了一下,就不会有问题了

人造人 发表于 2018-9-7 21:08:10

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

易晓外 发表于 2018-9-7 21:27:19

“C”语言的“feof()”函数和数据库中“eof()”函数的运作是完全不同的。数据库中“eof()”函数读取当前指针的位置,“C”语言的“feof()”函数返回的是最后一次“读操作的内容”。多年来把“位置和内容”相混,从而造成了对这一概念的似是而非。

那么,位置和内容到底有何不同呢?举个简单的例子,比如有人说“你走到火车的最后一节车箱”这就是位置。而如果说“请你一直向后走,摸到铁轨结束”这就是内容。也就是说用内容来判断会“多走一节”。这就是完全依赖于“while(!feof(FP)){...}”进行文件复制时,目标文档总会比源文档“多出一些”的原因。
这是错误原因!!!
页: [1]
查看完整版本: 求帮助,非常着急,大佬们,有关链表与文件的