标题:读取文件时只能读取一个节点,文件里超过一个,读取的时候就会产生一个访问 ...
只看楼主
孤鹄
Rank: 1
等 级:新手上路
帖 子:9
专家分:0
注 册:2018-1-10
结帖率:100%
已结贴  问题点数:20 回复次数:13 
读取文件时只能读取一个节点,文件里超过一个,读取的时候就会产生一个访问违例(段异常),请大佬们帮忙看看!!
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define LEN sizeof(struct book)
struct book
{
    char name[20];
    long int number;
    struct book *next;
};
struct book *add(struct book *head)
{
    struct book *p,*t;
    p=(struct book*)malloc(LEN);
    printf("请输入您要增加的联系人的名字:");
    scanf("%s",p->name);
    printf("请输入号码:");
    scanf("%ld",&p->number);
    p->next=NULL;
    t=head;
    if(head==NULL)
    {
         head=p;
         return(head);
    }
    else if(strcmp(p->name,head->name)<0)
        {
            p->next=head;
            head=p;
            return(head);
        }
    else if (t->next!=NULL)
        do
        {if(strcmp(t->name,p->name)<0&&strcmp((t->next)->name,p->name)>0)
        {  
            p->next=t->next;
            t->next=p;
            break;
        }
 
        t=t->next;
        }while(t->next!=NULL);
        if( t->next==NULL)
            t->next=p;
    return(head);
}

void print(struct book * head)
{
    if(head==NULL)
    {
      printf("您已经帅到没朋友了!\n");
     }
    while(head!=NULL)
    {
        printf("%s   %ld\n",head->name,head->number);
        head=head->next;
    }
}
struct book *del(struct book *head)
{
    if(head==NULL)
   {
        printf("您已经没有联系人可删了!\n");
        return(head);
    }
    char MZ[20];
    printf("请输入您要删除的联系人:");
    scanf("%s",MZ);
    struct book *p,*t;
    t=head;
    if(strcmp(head->name,MZ)==0)
        {
            head=t->next;
            free(t);
            printf("删除完成!");
            return(head);
        }
    do
        {            
            if(strcmp(t->name,MZ)<0&&strcmp((t->next)->name,MZ)==0)
        {   p=t->next;
            t->next=p->next;
            free(p);
            printf("删除完成!");
            return(head);
        }
        t=t->next;
        }while(t!=NULL);
     if(t==NULL)
        {printf("您是不是找错人啦!?\n");
                return(head); }
}
void find(struct book *head)
{
    struct book *p;
    char MZ[20];
    printf("请输入您要寻找的联系人:");
    scanf("%s",MZ);
    p=head;
    if(p!=NULL)
        do
        {if(strcmp(p->name,MZ)==0)
        {
            printf("%s的号码为:%ld.\n",MZ,p->number);
            break;
        }
        p=p->next;
        }while(p!=NULL);
    if(p==NULL)
        printf("您的联系人走丢了!\n");
}
struct book*load(book *head)
{
    struct book *p,*t;
    FILE *fp;
    if((fp=fopen("stu.list","rb"))==NULL)
    {printf("读取失败!\n");
    fclose(fp);
    return(head);
    }
    for(p=(struct book*)malloc(LEN);;p=(struct book*)malloc(LEN))
    {
                  if(fread(p,LEN,1,fp)==1)
      {
      if(head==NULL)
        {
         t=head=p;
        }
    else if(strcmp(p->name,head->name)<0)
        {
            p->next=head;
            t=head=p;
        }
    else if (t->next!=NULL)
        do
        {if(strcmp(t->name,p->name)<0&&strcmp((t->next)->name,p->name)>0)
        {  
            p->next=t->next;
            t->next=p;break;
        }
 
        t=t->next;
        }while(t->next!=NULL);
      else if( t->next==NULL)
            t->next=p;                     
       }
    if(feof(fp))
    break;
    }
    printf("蹬蹬蹬等!加载成功!!\n");
    fclose(fp);
    return (head);
}
void save(struct book* head)
{
    FILE*fp;
    if((fp=fopen("stu.list","wb"))==NULL)
    {
          printf("无法打开文件!\n");
          return;
    }
    for(;head!=NULL;head=head->next)
         if(fwrite(head,LEN,1,fp)!=1)
         {
          printf("存储失败!\n");
          fclose(fp);
          }
     fclose(fp);
}
int main()
{
    struct book*head;
    int i,t=1;
    head=NULL;
    head=load(head);
    while(t==1)
    { printf("请按回车来到主界面");
        fflush(stdin);//清空键盘缓冲区
        getchar();
        fflush(stdin);//清空键盘缓冲区
    system("cls");//清屏
    printf("╔═════════════════╗\n");
    printf("║          电话本管理程序          ║\n");
    printf("╠═════════════════╣\n");
    printf("║        1 加入一个新联系人        ║\n");
    printf("║        2 删除一个联系人          ║\n");
    printf("║        3 查找电话本中的联系人    ║\n");
    printf("║        4 显示已存联系人          ║\n");
    printf("║        5 退      出              ║\n");
    printf("╚═════════════════╝\n");
    printf("请选择:");
       scanf("%d",&i);
       switch(i)
       {
        case 1:head=add(head);break;
        case 2:head=del(head);break;
        case 3:find(head);break;
        case 4:print(head);break;
        case 5:save(head);printf("感谢您的使用!\n");return 0;
        }
    }
}
搜索更多相关主题的帖子: name next head printf NULL 
2018-01-10 16:14
grmmylbs
Rank: 14Rank: 14Rank: 14Rank: 14
等 级:贵宾
威 望:54
帖 子:1409
专家分:5845
注 册:2016-2-14
得分:0 
最好把文件发一下
2018-01-10 16:31
孤鹄
Rank: 1
等 级:新手上路
帖 子:9
专家分:0
注 册:2018-1-10
得分:0 
运行一遍会自动生成文件的,就是生成文件后再次进入的读取有问题
2018-01-10 16:39
孤鹄
Rank: 1
等 级:新手上路
帖 子:9
专家分:0
注 册:2018-1-10
得分:0 
可能是每次读取一个尾部指针要置空吧,但这样好像下次生成文件时会有问题
2018-01-10 16:42
孤鹄
Rank: 1
等 级:新手上路
帖 子:9
专家分:0
注 册:2018-1-10
得分:0 
回复 2楼 grmmylbs
运行一遍会自动生成文件的,就是生成文件后再次进入的读取有问题,可能是每次读取一个尾部指针要置空吧,但这样好像下次生成文件时会有问题
2018-01-10 16:43
Jonny0201
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:52
帖 子:488
专家分:2603
注 册:2016-11-7
得分:8 

当循环进入第二次的时候,就会跳到这个 elseif,但是对应的 t->next->name 地址有问题
看你写的应该是不带头结点的循环单链表
更改的地方用红色标出来了,最后在我这是没问题了
另外,你这代码,把我的编译器搞崩溃了,要删除缓存才能重新打开

#include <iostream>
#include <stdlib.h>
#include <string.h>
#define LEN sizeof(struct book)
struct book
{
        char name[20];
        long int number;
        struct book *next;
};
struct book *add(struct book *head)
{
        struct book *p,*t;
        p=(struct book*)malloc(LEN);
        printf("请输入您要增加的联系人的名字:");
        scanf("%s",p->name);
        printf("请输入号码:");
        scanf("%ld",&p->number);
        p->next=NULL;
        t=head;
        if(head==NULL)
        {
                 head=p;
                 return(head);
        }
        else if(strcmp(p->name,head->name)<0)
                {
                        p->next=head;
                        head=p;
                        return(head);
                }
        else if (t->next!=NULL)
                do
                {if(strcmp(t->name,p->name)<0&&strcmp((t->next)->name,p->name)>0)
                {  
                        p->next=t->next;
                        t->next=p;
                        break;
                }
 
                t=t->next;
                }while(t->next!=NULL);
                if( t->next==NULL)
                        t->next=p;
        return(head);
}

void print(struct book * head)
{
        if(head==NULL)
        {
            printf("您已经帅到没朋友了!\n");
         }
        while(head!=NULL)
        {
            if(head->next != head) {
                printf("%s   %ld\n",head->name,head->number);
                head=head->next;
            }else {
                break;
            }
        }
}
struct book *del(struct book *head)
{
        if(head==NULL)
     {
                printf("您已经没有联系人可删了!\n");
                return(head);
        }
        char MZ[20];
        printf("请输入您要删除的联系人:");
        scanf("%s",MZ);
        struct book *p,*t;
        t=head;
        if(strcmp(head->name,MZ)==0)
                {
                        head=t->next;
                        free(t);
                        printf("删除完成!");
                        return(head);
                }
        do
                {            
                        if(strcmp(t->name,MZ)<0&&strcmp((t->next)->name,MZ)==0)
                {   p=t->next;
                        t->next=p->next;
                        free(p);
                        printf("删除完成!");
                        return(head);
                }
                if(t->next == head) {
                    break;
                }

                t=t->next;
                }while(t!=NULL);
         if(t==NULL)
                {printf("您是不是找错人啦!?\n");
                                return(head); }
}
void find(struct book *head)
{
        struct book *p;
        char MZ[20];
        printf("请输入您要寻找的联系人:");
        scanf("%s",MZ);
        p=head;
        if(p!=NULL)
                do
                {if(strcmp(p->name,MZ)==0)
                {
                        printf("%s的号码为:%ld.\n",MZ,p->number);
                        break;
                }
                p=p->next;
                if(p->next == head) {
                    break;
                }

                }while(p!=NULL);
        if(p==NULL)
                printf("您的联系人走丢了!\n");
}
struct book*load(book *head)
{
        struct book *p, *t;
        FILE *fp;
        if((fp=fopen("stu.list","rb"))==NULL)
        {printf("读取失败!\n");
        fclose(fp);
        return(head);
        }
        for(p=(struct book*)malloc(LEN);;p=(struct book*)malloc(LEN))
                {
                                            if(fread(p,LEN,1,fp)==1)
                    {
                    if(head==NULL)
                        {
                         t=head=p;
                        }
                else if(strcmp(p->name,head->name)<0)
                        {
                                p->next=head;
                                t=head=p;
                        }
                else if (t->next!=NULL)
                        do
                        {
                            t->next = p;
                            if(strcmp(t->name,p->name)<0&&strcmp((t->next)->name,p->name)>0)
                        {  
                                p->next=t->next;
                                t->next=p;break;
                        }
         
                        t=t->next;
                        }while(t->next!=p);
                    else if( t->next==NULL)
                                t->next=p;                     
                     }
                if(feof(fp))
                break;
                }
        printf("蹬蹬蹬等!加载成功!!\n");
        fclose(fp);
        return (head);
}
void save(struct book* head)
{
        FILE*fp;
        if((fp=fopen("stu.list","wb"))==NULL)
        {
                    printf("无法打开文件!\n");
                    return;
        }
        for(;head!=NULL;head=head->next){
                 if(fwrite(head,LEN,1,fp)!=1)
                 {
                    printf("存储失败!\n");
                    fclose(fp);
                    
                    }
                    if(head->next == head) {
                        break;
                    }

        }
                    
         fclose(fp);
}
int main()
{
        struct book*head;
        int i,t=1;
        head=NULL;
        head=load(head);
        while(t==1)
        { printf("请按回车来到主界面");
                fflush(stdin);//清空键盘缓冲区
                getchar();
                fflush(stdin);//清空键盘缓冲区
        system("cls");//清屏
        printf("╔═════════════════╗\n");
        printf("║          电话本管理程序          ║\n");
        printf("╠═════════════════╣\n");
        printf("║        1 加入一个新联系人        ║\n");
        printf("║        2 删除一个联系人          ║\n");
        printf("║        3 查找电话本中的联系人    ║\n");
        printf("║        4 显示已存联系人          ║\n");
        printf("║        5 退      出              ║\n");
        printf("╚═════════════════╝\n");
        printf("请选择:");
             scanf("%d",&i);
             switch(i)
             {
                case 1:head=add(head);break;
                case 2:head=del(head);break;
                case 3:find(head);break;
                case 4:print(head);break;
                case 5:save(head);printf("感谢您的使用!\n");return 0;
                }
        }
}
2018-01-10 17:33
Jonny0201
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:52
帖 子:488
专家分:2603
注 册:2016-11-7
得分:0 
另外,能否告知访问违例(段异常)这两个词代表的意思
还有 if 条件中的 strcmp()  函数的作用?
2018-01-10 17:34
forever74
Rank: 12Rank: 12Rank: 12
来 自:CC
等 级:贵宾
威 望:49
帖 子:1636
专家分:3940
注 册:2007-12-27
得分:0 
作为常识,分配内存是个动态过程,因此你把结点里面的指针保存下来是毫无意义的,
进一步说,正因为你保存了指针的值,下次读进来居然还要根据这个值去访存,构成了段异常,性质和访问野指针目标是一样的。

BTW:只保存数据,读文件的过程应该重新建立整个数据结构。

[此贴子已经被作者于2018-1-10 20:37编辑过]


对宇宙最严谨的描述应该就是宇宙其实是不严谨的
2018-01-10 20:31
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:12 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LEN sizeof(struct book)

struct book
{
    char name[20];
    long int number;
    struct book *next;
};

void _free(struct book *head)
{
    struct book *p;
    while (head)
    {
        p = head->next;
        free(head);
        head = p;
    }
}

struct book *_insert_sort(struct book *head, struct book *sb)
{
    struct book *p, *q, *s;
    p = head;
    q = NULL;
    s = (struct book *)malloc(LEN);
    *s = *sb;
    s->next = NULL;
    while (p)
    {
        if (strcmp(p->name,sb->name) >= 0)
        {
            s->next = p;
            break;
        }
        q = p;
        p = p->next;
    }
    if (q)
        q->next = s;
    else
        head = s;
    return head;
}

struct book *add(struct book *head)
{
    struct book sb;
    printf("请输入您要增加的联系人的名字:");
    scanf("%s", sb.name);
    printf("请输入号码:");
    scanf("%ld", &sb.number);
    head = _insert_sort(head, &sb);
    return head;
}

void print(struct book * head)
{
    for (; head; head=head->next)
        printf("%s   %ld\n", head->name, head->number);
    printf("\n");
}

struct book *del(struct book *head)
{
    if(head==NULL)
    {
        printf("您已经没有联系人可删了!\n");
        return head;
    }
    char MZ[20];
    printf("请输入您要删除的联系人:");
    scanf("%s",MZ);
    struct book *p,*t;
    if (strcmp(head->name,MZ)==0)
    {
        t = head->next;
        free(head);
        printf("删除完成!\n");
        return t;
    }
    p = head;
    t = head->next;
    while (t)
    {
        if (strcmp(t->name,MZ) == 0)
        {
            p->next = t->next;
            free(t);
            printf("删除完成!\n");
            return head;
        }
        p = t;
        t = t->next;
    }
    printf("您是不是找错人啦!?\n");
    return head;
}

void find(struct book *head)
{
    char MZ[20];
    printf("请输入您要寻找的联系人:");
    scanf("%s",MZ);
    for (; head; head=head->next)
        if (strcmp(head->name,MZ) == 0)
            break;
    if (head == NULL)
    {
        printf("您的联系人走丢了!\n");
        return;
    }
    for (; head; head=head->next)
        if (strcmp(head->name,MZ) == 0)
            printf("%s的号码为:%ld\n",head->name,head->number);
}

struct book *load()
{
    FILE *fp=fopen("stu.list","rb");
    if (fp == NULL)
    {
        printf("无法打开文件!\n");
        return NULL;
    }
    struct book sb, *head=NULL, *p;
    while (fread(&sb,LEN,1,fp)==1)
        head = _insert_sort(head, &sb);
    fclose(fp);
    return head;
}

void save(struct book *head)
{
    FILE *fp=fopen("stu.list","wb");
    if (fp == NULL)
    {
        printf("无法打开文件!\n");
        return;
    }
    for (; head; head=head->next)
    {
        if (fwrite(head,LEN,1,fp)!=1)
        {
            printf("存储失败!\n");
            break;
        }
    }
    fclose(fp);
    _free(head);
}

int main()
{
    struct book *head = load();
    int i;
    do
    {
        system("cls");//清屏
        printf("╔═════════════════╗\n");
        printf("║          电话本管理程序          ║\n");
        printf("╠═════════════════╣\n");
        printf("║        1 加入一个新联系人        ║\n");
        printf("║        2 删除一个联系人          ║\n");
        printf("║        3 查找电话本中的联系人    ║\n");
        printf("║        4 显示已存联系人          ║\n");
        printf("║        5 退      出              ║\n");
        printf("╚═════════════════╝\n");
        printf("请选择:");
        //fflush(stdin);//清空键盘缓冲区
        scanf("%d",&i);
        while (getchar()!='\n');
        switch(i)
        {
            case 1:
                head = add(head);
                break;
            case 2:
                head=del(head);
                break;
            case 3:
                find(head);
                break;
            case 4:
                print(head);
                break;
            case 5:
                save(head);
                printf("感谢您的使用!\n");
                break;
        }
        system("pause");
    }
    while (i != 5);
    return 0;
}
2018-01-10 22:38
孤鹄
Rank: 1
等 级:新手上路
帖 子:9
专家分:0
注 册:2018-1-10
得分:0 
回复 7楼 Jonny0201
访问违例(段异常)我也不太了解,strcmp是比较两个字符大小,若前小于后,则小于0,反之大于0
2018-01-10 23:23



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-484129-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.015900 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved