鱼C论坛

 找回密码
 立即注册
查看: 864|回复: 7

[已解决]在第二次调用查找函数的时候就出错,能帮我看看吗?

[复制链接]
发表于 2020-2-23 16:28:57 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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

typedef struct Telbook
{
        char name[12];
        char number[15];
        char beizhu[24];
        struct Telbook *next;
} PLR,*PLRPIN;


void PrintInfo(PLRPIN Info);
void InsertInfo(PLRPIN *Info); //把地址给它,用*把系统分给头指针的地址里的值拿出来做修改,就可以指向其它的值,所以要两层引用
void InputInfo(PLRPIN);
void releaseInfo(PLRPIN *Info);//释放所有内存空间,不是一个结构哟
void searchInfo(PLRPIN Info);
void DelInfo(PLRPIN *Info);
void ModfiyInfo(PLRPIN *INFO);


#define ME_ALLCARD 1
#define ME_FOUNDCARD 2
#define ME_DELCARD 3
#define ME_MODIFYCARD 4
#define ME_NEWCARD 5
#define ME_EXIT 0

#define _CRT_SECURE_NO_WARNINGS //排错

int main()
{
        int iMenu;
        char cExit,cInput;
        PLRPIN Headr=NULL; //声明一个头指针,并给值等0;

        
        do
        {
                printf("\n|-------------------------------|菜单|-----------------------------------|\n\n");
                printf("|  1.显示所有名片|2.查找名片|3.删除名片|4.修改名片|5.新建名片|0.退出  |\n\n");
                printf("|--------------------------------------------------------------------------|\n");

                printf("\n请输入数字选择菜单:");
reInput:
                scanf("%d",&iMenu); //条件选择菜单
                switch(iMenu)
                {
                case ME_ALLCARD:
                        PrintInfo(Headr);
                        break;
                case ME_FOUNDCARD:
                
                        searchInfo(Headr);
                        break;
                case ME_DELCARD:
                        DelInfo(&Headr);
                        break;
                case ME_NEWCARD:
                        while(1)
                        {
                                printf("请问是否要新建名片(Y/N):");
                                do
                                {
                                        cInput=getchar();

                                }while(cInput !='Y' && cInput != 'N');
                                if(cInput == 'Y')
                                {
                                        InsertInfo(&Headr);
                                }
                                else
                                {
                                        break;
                                }
                        }
                        
                        break;
                case ME_MODIFYCARD:
                        ModfiyInfo(&Headr);
                        break;
                case ME_EXIT:
                        printf("感谢您的使用,程序准备退出!\n确认退出请输入(Y/N):");
                        do
                        {
                        cExit=getchar();
                        }while(cExit != 'Y' && cExit != 'N');
                        if(cExit == 'Y')
                        {
                                releaseInfo(&Headr);
                                exit(1);
                        }
                        break;
                default :
                        printf("输入的选项无效,请重新输入(1~5):");
                        goto reInput;
                        break;
                }
        }while(1);
        //releaseInfo(&Headr);
        return 0;
}


void DelInfo(PLRPIN *Info) //删除信息
{
        char cName[24];
        char cYesNo;
        PLRPIN Current,Previous;

        printf("请输入要删除的名片姓名:");
        scanf("%s",cName);
        printf("确定要删除 %s 吗?(Y/N):",cName);
        do
        {
                
                cYesNo = getchar();
        }while (cYesNo != 'Y' && cYesNo != 'N');
        
        if(cYesNo == 'Y')
        {
                Current = *Info;
                Previous = NULL;

                while(Current != NULL && Current->name == cName) //搜查符合的条件
                {
                        Previous =Current;
                        Current=Current->next;
                }
                if(Current == NULL)
                {
                        printf("没有找到要删除的名片,请确认您的输入!\n");
                        return ;
                }
                else
                {
                        if(Previous == NULL)
                        {
                                *Info=Current->next;

                        }
                        else
                        {
                                Previous->next=Current->next;
                        }
                        printf("删除成功!\n");
                         free(Current);
                }
        }
}

void InsertInfo(PLRPIN *Info) //传入指向指针结构的指针来修改指针/拿到头指指针就能操作单链表,所有主函数里的是头指针,传递给其它函数便于操作。
{
        PLRPIN Temp,New;
        static PLRPIN Nup; //尾插法的重点,必须是静态变量,才能一直指向NULL
        New=(PLRPIN)malloc(sizeof(PLR));

        if(NULL == New)
        {
                printf("新的空间分配失败\n");
                return ;
        }

        InputInfo(New);
        //--------------------尾插法---------------------------------
        if(*Info != NULL)
        {
                Nup->next = New;
                New->next=NULL;

                /*------------遍历效率代------------------
                while (Temp->next != NULL)
                {
                        //Temp = Temp->next; //搜查NULL
                }
                //找到NULL插入数据
                Temp->next= New;
                New->next = NULL;
                ---------------------------*/
        }
        else
        {
                *Info = New;
                New->next = NULL;
        }
                Nup=New;
        /**************************头插法*********************************
        if(*Info != NULL) 
        {
                Temp=*Info; //把头指针放入TEMP 再把新的转接赋值达到插入的目的。
                *Info=New;
                New->next=Temp;
        }
        else
        {
                *Info=New;
                New->next=NULL;
        }
        *******************************************************************/
}

void InputInfo(PLRPIN Info) //输入信息
{
        PLRPIN New;
        New=Info;
        printf("请输入姓名:");
        scanf("%s",New->name);
        printf("请给人物职业:");
        scanf("%s",New->beizhu);
        printf("请输入号码:");
        scanf("%s",New->number);
}

void PrintInfo(PLRPIN Info) //打印输出
{
        
        PLRPIN New;
        int count =1;

        New=Info;

        printf("\n\n|------------------------------|通迅录|----------------------------------|\n\n");
        printf("|编号|\t|姓名|\t|职业|\t|联系方式|\n");
        while(New != NULL )
        {
                printf("%5d%17s%18s%21s\n",count,New->name,New->beizhu,New->number);
                New=New->next;
                count++;
        }
        putchar('\n');
}

void releaseInfo(PLRPIN *Info) //释放空间
{
        PLRPIN Temp;
        while (*Info != NULL)
        {
                Temp=*Info;
                *Info=(*Info)->next;
                free(Temp);
        }
}

void searchInfo(PLRPIN Info)  //查找信息
{
        char target[128];
        PLRPIN New;
        printf("请输入要找查名片的信息[姓名,职业,电话号码] :");
        scanf("%s",target);

        New=Info;

        while(New != NULL)
        {
                if(!strcmp(New->name,target) || !strcmp(New->beizhu,target) || !strcmp(New->number,target))
                {
                        break;
                }
                New = New->next;
        }


        if(New == NULL)
        {
                printf("很抱赚,没有找到您要的结果!\n");
        }
        else
        {
                do
                {
                        printf("已找到符合条件的名片...\n");
                        PrintInfo(New);
                }while(New->next != NULL);                
        }

        releaseInfo(&New);
        
}


void ModfiyInfo(PLRPIN *Info)  //修改信息
{
        char cName[24];
        char cYesNo;
        PLRPIN Current;

        printf("请输入要修改名片的姓名:");
        scanf("%s",cName);
        printf("确定要修改 %s 信息吗?(Y/N):",cName);

        do
        {
                cYesNo = getchar();
        }while (cYesNo != 'Y' && cYesNo != 'N');
        
        if(cYesNo == 'Y')
        {
                Current = *Info;
                

                while(Current != NULL && Current->name == cName) //搜查符合的条件
                {
                        Current=Current->next;
                }
                if(Current == NULL)
                {
                        printf("没有找到要修改的名片,请确认您的输入!\n");
                        return ;
                }
                else
                {
                        printf("找到匹配:%s %s %s\n",Current->name,Current->beizhu,Current->number );
                        printf("将%s修改为:",Current->name);
                        scanf("%s",Current->name);

                        printf("将%s修改为:",Current->beizhu);
                        scanf("%s",Current->beizhu);

                        printf("将%s修改为:",Current->number);
                        scanf("%s",Current->number);
                        printf("修改后的信息为:%s %s %s\n",Current->name,Current->beizhu,Current->number );
                        printf("修改成功!\n");
                }
        }
}


第二次调用查找函数就出错,但不知道是什么原因。
最佳答案
2020-2-25 16:08:41
帮你修改了。
主要是DelInfo()和searcheInfo();详细看注释。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Telbook
{
    char name[12];
    char number[15];
    char beizhu[24];
    struct Telbook *next;
} PLR, *PLRPIN;

void PrintInfo(PLRPIN Info);
void InsertInfo(PLRPIN *Info); //把地址给它,用*把系统分给头指针的地址里的值拿出来做修改,就可以指向其它的值,所以要两层引用
void InputInfo(PLRPIN);
void releaseInfo(PLRPIN *Info); //释放所有内存空间,不是一个结构哟
void searchInfo(PLRPIN Info);
void DelInfo(PLRPIN *Info);
void ModfiyInfo(PLRPIN *INFO);

#define ME_ALLCARD 1
#define ME_FOUNDCARD 2
#define ME_DELCARD 3
#define ME_MODIFYCARD 4
#define ME_NEWCARD 5
#define ME_EXIT 0

#define _CRT_SECURE_NO_WARNINGS //排错

int main()
{
    int iMenu;
    char cExit, cInput;
    PLRPIN Headr = NULL; //声明一个头指针,并给值等0;

    do
    {
        printf("\n|-------------------------------|菜单|-----------------------------------|\n\n");
        printf("|  1.显示所有名片|2.查找名片|3.删除名片|4.修改名片|5.新建名片|0.退出  |\n\n");
        printf("|--------------------------------------------------------------------------|\n");

        printf("\n请输入数字选择菜单:");
    reInput:
        scanf("%d", &iMenu); //条件选择菜单
        switch (iMenu)
        {
        case ME_ALLCARD:
            PrintInfo(Headr);
            break;
        case ME_FOUNDCARD:
            searchInfo(Headr);
            break;
        case ME_DELCARD:
            DelInfo(&Headr);
            break;
        case ME_NEWCARD:
            while (1)
            {
                printf("请问是否要新建名片(Y/N):");
                do
                {
                    cInput = getchar();

                } while (cInput != 'Y' && cInput != 'N');
                if (cInput == 'Y')
                {
                    InsertInfo(&Headr);
                }
                else
                {
                    break;
                }
            }
            break;
        case ME_MODIFYCARD:
            ModfiyInfo(&Headr);
            break;
        case ME_EXIT:
            printf("感谢您的使用,程序准备退出!\n确认退出请输入(Y/N):");
            do
            {
                cExit = getchar();
            } while (cExit != 'Y' && cExit != 'N');
            if (cExit == 'Y')
            {
                releaseInfo(&Headr);
                exit(1);
            }
            break;
        default:
            printf("输入的选项无效,请重新输入(1~5):");
            goto reInput;
            break;
        }
    } while (1);
    //releaseInfo(&Headr);
    return 0;
}

void DelInfo(PLRPIN *Info) //删除信息
{
    char cName[24];
    char cYesNo;
    PLRPIN Current, Previous;

    printf("请输入要删除的名片姓名:");
    scanf("%s", cName);
    printf("确定要删除 %s 吗?(Y/N):", cName);
    do
    {
        cYesNo = getchar();
    } while (cYesNo != 'Y' && cYesNo != 'N');

    if (cYesNo == 'Y')
    {
        Current = *Info;
        Previous = NULL;
        //while (Current != NULL && Current->name == cName) //这里逻辑错误;应该是Current->name!=name
        while (Current != NULL && strcmp(Current->name, cName))
        {
            Previous = Current;
            Current = Current->next;
        }

        if (Current == NULL)
        {
            printf("没有找到要删除的名片,请确认您的输入!\n");
            return;
        }
        else
        {
            if (Previous == NULL)
            {
                *Info = Current->next;
            }
            else
            {
                Previous->next = Current->next;
            }
            printf("删除成功!\n");
            free(Current);
        }
    }
}

void InsertInfo(PLRPIN *Info) //传入指向指针结构的指针来修改指针/拿到头指指针就能操作单链表,所有主函数里的是头指针,传递给其它函数便于操作。
{
    PLRPIN Temp, New;
    static PLRPIN Nup; //尾插法的重点,必须是静态变量,才能一直指向NULL
    New = (PLRPIN)malloc(sizeof(PLR));

    if (NULL == New)
    {
        printf("新的空间分配失败\n");
        return;
    }

    InputInfo(New);
    //--------------------尾插法---------------------------------
    if (*Info != NULL)
    {
        Nup->next = New;
        New->next = NULL;

        /*------------遍历效率代------------------
                while (Temp->next != NULL)
                {
                        //Temp = Temp->next; //搜查NULL
                }
                //找到NULL插入数据
                Temp->next= New;
                New->next = NULL;
                ---------------------------*/
    }
    else
    {
        *Info = New;
        New->next = NULL;
    }
    Nup = New;
    /**************************头插法*********************************
        if(*Info != NULL) 
        {
                Temp=*Info; //把头指针放入TEMP 再把新的转接赋值达到插入的目的。
                *Info=New;
                New->next=Temp;
        }
        else
        {
                *Info=New;
                New->next=NULL;
        }
        *******************************************************************/
}

void InputInfo(PLRPIN Info) //输入信息
{
    PLRPIN New;
    New = Info;
    printf("请输入姓名:");
    scanf("%s", New->name);
    printf("请给人物职业:");
    scanf("%s", New->beizhu);
    printf("请输入号码:");
    scanf("%s", New->number);
}

void PrintInfo(PLRPIN Info) //打印输出
{

    PLRPIN New;
    int count = 1;

    New = Info;

    printf("\n\n|------------------------------|通迅录|----------------------------------|\n\n");
    printf("|编号|\t|姓名|\t|职业|\t|联系方式|\n");
    while (New != NULL)
    {
        printf("%5d%17s%18s%21s\n", count, New->name, New->beizhu, New->number);
        New = New->next;
        count++;
    }
    putchar('\n');
}

void releaseInfo(PLRPIN *Info) //释放空间
{
    PLRPIN Temp;
    while (*Info != NULL)
    {
        Temp = *Info;
        *Info = (*Info)->next;
        free(Temp);
    }
}

void searchInfo(PLRPIN Info) //查找信息
{
    char target[128];
    PLRPIN New;
    printf("请输入要找查名片的信息[姓名,职业,电话号码] :");
    scanf("%s", target);

    New = Info;
    PLRPIN founded=NULL;
    
    // while (New != NULL)
    // {
    //     if (!strcmp(New->name, target) || !strcmp(New->beizhu, target) || !strcmp(New->number, target))
    //     {
    //         break;
    //     }
    //     New = New->next;
    // } //这一块有问题,只找到第一个符号条件的名片。

    while (New != NULL) // 查找目标名片,把所有找到的名片用新链表founded指示
    {
        if (!strcmp(New->name, target) || !strcmp(New->beizhu, target) || !strcmp(New->number, target))
        {
            PLRPIN node= (PLRPIN)malloc(sizeof(PLR)); // 新建结点存储搜索到的结点
            *node = *New; //将找到的名片内容copy到新链表中
            node->next = NULL; //next 复位,防止影响原链表内容
            if (founded == NULL)
            {
                founded = node;
            }
            else
            {
                founded->next = node;
            }
        }
        New = New->next;
    }

    if (founded == NULL)
    {
        printf("很抱赚,没有找到您要的结果!\n");
    }
    else
    {
        printf("已找到符合条件的名片...\n");
        PrintInfo(founded); // 打印搜索处理的名片
        // do
        // {
        //     printf("已找到符合条件的名片...\n");
        //     //PrintInfo(New);//这个函数是从New所指的结点打印之后的所有名片啊!这样调用有问题吧;

        // } while (New->next != NULL);
    }
    releaseInfo(&founded); // 打印完成后释放掉新建的链表

    //releaseInfo(&New); //不能调用releaseInfo; New所指向的名片结点和Info中的某些结点是共用的。
                         //调用之后,会把Info中与指针New地址相同的结点之后的所有结点的内存空间释放掉
}

void ModfiyInfo(PLRPIN *Info) //修改信息
{
    char cName[24];
    char cYesNo;
    PLRPIN Current;

    printf("请输入要修改名片的姓名:");
    scanf("%s", cName);
    printf("确定要修改 %s 信息吗?(Y/N):", cName);

    do
    {
        cYesNo = getchar();
    } while (cYesNo != 'Y' && cYesNo != 'N');

    if (cYesNo == 'Y')
    {
        Current = *Info;

        while (Current != NULL && Current->name == cName) //搜查符合的条件
        {
            Current = Current->next;
        }
        if (Current == NULL)
        {
            printf("没有找到要修改的名片,请确认您的输入!\n");
            return;
        }
        else
        {
            printf("找到匹配:%s %s %s\n", Current->name, Current->beizhu, Current->number);
            printf("将%s修改为:", Current->name);
            scanf("%s", Current->name);

            printf("将%s修改为:", Current->beizhu);
            scanf("%s", Current->beizhu);

            printf("将%s修改为:", Current->number);
            scanf("%s", Current->number);
            printf("修改后的信息为:%s %s %s\n", Current->name, Current->beizhu, Current->number);
            printf("修改成功!\n");
        }
    }
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-2-23 22:14:36 | 显示全部楼层
本帖最后由 4goodworld 于 2020-2-23 22:15 编辑

个人探讨,你这个检索,为啥要循环呢?
  do
                {
                        printf("已找到符合条件的名片...\n");
                        PrintInfo(New);
                }while(New->next != NULL);      
你这个打印函数为啥要循环打印呢?找到了一个,不应该打印一个?
    while(New != NULL )
        {
                printf("%5d%17s%18s%21s\n",count,New->name,New->beizhu,New->number);
                New=New->next;
                count++;
        }
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-23 23:34:14 | 显示全部楼层
4goodworld 发表于 2020-2-23 22:14
个人探讨,你这个检索,为啥要循环呢?

你这个打印函数为啥要循环打印呢?找到了一个,不应该打印一个? ...

因为有可能会找到两个,必如我输入职业:有3个是职业是一样的就可以全打出来,还有就是显示所有的时候
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-23 23:36:04 | 显示全部楼层
4goodworld 发表于 2020-2-23 22:14
个人探讨,你这个检索,为啥要循环呢?

你这个打印函数为啥要循环打印呢?找到了一个,不应该打印一个? ...

您帮我测试一下,第二次调用查找函数就出错什么原因呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-23 23:54:22 | 显示全部楼层
黄翼 发表于 2020-2-23 23:34
因为有可能会找到两个,必如我输入职业:有3个是职业是一样的就可以全打出来,还有就是显示所有的时候

我个人的建议,你得把自己的函数构思好、设计好,很多东西杂在一起,反而前后制约,让你顾此失彼。
如果打印只打印一个
然后,是不是就可以在搜索里优化,继续搜下去然后继续打印
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-25 16:08:41 | 显示全部楼层    本楼为最佳答案   
帮你修改了。
主要是DelInfo()和searcheInfo();详细看注释。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Telbook
{
    char name[12];
    char number[15];
    char beizhu[24];
    struct Telbook *next;
} PLR, *PLRPIN;

void PrintInfo(PLRPIN Info);
void InsertInfo(PLRPIN *Info); //把地址给它,用*把系统分给头指针的地址里的值拿出来做修改,就可以指向其它的值,所以要两层引用
void InputInfo(PLRPIN);
void releaseInfo(PLRPIN *Info); //释放所有内存空间,不是一个结构哟
void searchInfo(PLRPIN Info);
void DelInfo(PLRPIN *Info);
void ModfiyInfo(PLRPIN *INFO);

#define ME_ALLCARD 1
#define ME_FOUNDCARD 2
#define ME_DELCARD 3
#define ME_MODIFYCARD 4
#define ME_NEWCARD 5
#define ME_EXIT 0

#define _CRT_SECURE_NO_WARNINGS //排错

int main()
{
    int iMenu;
    char cExit, cInput;
    PLRPIN Headr = NULL; //声明一个头指针,并给值等0;

    do
    {
        printf("\n|-------------------------------|菜单|-----------------------------------|\n\n");
        printf("|  1.显示所有名片|2.查找名片|3.删除名片|4.修改名片|5.新建名片|0.退出  |\n\n");
        printf("|--------------------------------------------------------------------------|\n");

        printf("\n请输入数字选择菜单:");
    reInput:
        scanf("%d", &iMenu); //条件选择菜单
        switch (iMenu)
        {
        case ME_ALLCARD:
            PrintInfo(Headr);
            break;
        case ME_FOUNDCARD:
            searchInfo(Headr);
            break;
        case ME_DELCARD:
            DelInfo(&Headr);
            break;
        case ME_NEWCARD:
            while (1)
            {
                printf("请问是否要新建名片(Y/N):");
                do
                {
                    cInput = getchar();

                } while (cInput != 'Y' && cInput != 'N');
                if (cInput == 'Y')
                {
                    InsertInfo(&Headr);
                }
                else
                {
                    break;
                }
            }
            break;
        case ME_MODIFYCARD:
            ModfiyInfo(&Headr);
            break;
        case ME_EXIT:
            printf("感谢您的使用,程序准备退出!\n确认退出请输入(Y/N):");
            do
            {
                cExit = getchar();
            } while (cExit != 'Y' && cExit != 'N');
            if (cExit == 'Y')
            {
                releaseInfo(&Headr);
                exit(1);
            }
            break;
        default:
            printf("输入的选项无效,请重新输入(1~5):");
            goto reInput;
            break;
        }
    } while (1);
    //releaseInfo(&Headr);
    return 0;
}

void DelInfo(PLRPIN *Info) //删除信息
{
    char cName[24];
    char cYesNo;
    PLRPIN Current, Previous;

    printf("请输入要删除的名片姓名:");
    scanf("%s", cName);
    printf("确定要删除 %s 吗?(Y/N):", cName);
    do
    {
        cYesNo = getchar();
    } while (cYesNo != 'Y' && cYesNo != 'N');

    if (cYesNo == 'Y')
    {
        Current = *Info;
        Previous = NULL;
        //while (Current != NULL && Current->name == cName) //这里逻辑错误;应该是Current->name!=name
        while (Current != NULL && strcmp(Current->name, cName))
        {
            Previous = Current;
            Current = Current->next;
        }

        if (Current == NULL)
        {
            printf("没有找到要删除的名片,请确认您的输入!\n");
            return;
        }
        else
        {
            if (Previous == NULL)
            {
                *Info = Current->next;
            }
            else
            {
                Previous->next = Current->next;
            }
            printf("删除成功!\n");
            free(Current);
        }
    }
}

void InsertInfo(PLRPIN *Info) //传入指向指针结构的指针来修改指针/拿到头指指针就能操作单链表,所有主函数里的是头指针,传递给其它函数便于操作。
{
    PLRPIN Temp, New;
    static PLRPIN Nup; //尾插法的重点,必须是静态变量,才能一直指向NULL
    New = (PLRPIN)malloc(sizeof(PLR));

    if (NULL == New)
    {
        printf("新的空间分配失败\n");
        return;
    }

    InputInfo(New);
    //--------------------尾插法---------------------------------
    if (*Info != NULL)
    {
        Nup->next = New;
        New->next = NULL;

        /*------------遍历效率代------------------
                while (Temp->next != NULL)
                {
                        //Temp = Temp->next; //搜查NULL
                }
                //找到NULL插入数据
                Temp->next= New;
                New->next = NULL;
                ---------------------------*/
    }
    else
    {
        *Info = New;
        New->next = NULL;
    }
    Nup = New;
    /**************************头插法*********************************
        if(*Info != NULL) 
        {
                Temp=*Info; //把头指针放入TEMP 再把新的转接赋值达到插入的目的。
                *Info=New;
                New->next=Temp;
        }
        else
        {
                *Info=New;
                New->next=NULL;
        }
        *******************************************************************/
}

void InputInfo(PLRPIN Info) //输入信息
{
    PLRPIN New;
    New = Info;
    printf("请输入姓名:");
    scanf("%s", New->name);
    printf("请给人物职业:");
    scanf("%s", New->beizhu);
    printf("请输入号码:");
    scanf("%s", New->number);
}

void PrintInfo(PLRPIN Info) //打印输出
{

    PLRPIN New;
    int count = 1;

    New = Info;

    printf("\n\n|------------------------------|通迅录|----------------------------------|\n\n");
    printf("|编号|\t|姓名|\t|职业|\t|联系方式|\n");
    while (New != NULL)
    {
        printf("%5d%17s%18s%21s\n", count, New->name, New->beizhu, New->number);
        New = New->next;
        count++;
    }
    putchar('\n');
}

void releaseInfo(PLRPIN *Info) //释放空间
{
    PLRPIN Temp;
    while (*Info != NULL)
    {
        Temp = *Info;
        *Info = (*Info)->next;
        free(Temp);
    }
}

void searchInfo(PLRPIN Info) //查找信息
{
    char target[128];
    PLRPIN New;
    printf("请输入要找查名片的信息[姓名,职业,电话号码] :");
    scanf("%s", target);

    New = Info;
    PLRPIN founded=NULL;
    
    // while (New != NULL)
    // {
    //     if (!strcmp(New->name, target) || !strcmp(New->beizhu, target) || !strcmp(New->number, target))
    //     {
    //         break;
    //     }
    //     New = New->next;
    // } //这一块有问题,只找到第一个符号条件的名片。

    while (New != NULL) // 查找目标名片,把所有找到的名片用新链表founded指示
    {
        if (!strcmp(New->name, target) || !strcmp(New->beizhu, target) || !strcmp(New->number, target))
        {
            PLRPIN node= (PLRPIN)malloc(sizeof(PLR)); // 新建结点存储搜索到的结点
            *node = *New; //将找到的名片内容copy到新链表中
            node->next = NULL; //next 复位,防止影响原链表内容
            if (founded == NULL)
            {
                founded = node;
            }
            else
            {
                founded->next = node;
            }
        }
        New = New->next;
    }

    if (founded == NULL)
    {
        printf("很抱赚,没有找到您要的结果!\n");
    }
    else
    {
        printf("已找到符合条件的名片...\n");
        PrintInfo(founded); // 打印搜索处理的名片
        // do
        // {
        //     printf("已找到符合条件的名片...\n");
        //     //PrintInfo(New);//这个函数是从New所指的结点打印之后的所有名片啊!这样调用有问题吧;

        // } while (New->next != NULL);
    }
    releaseInfo(&founded); // 打印完成后释放掉新建的链表

    //releaseInfo(&New); //不能调用releaseInfo; New所指向的名片结点和Info中的某些结点是共用的。
                         //调用之后,会把Info中与指针New地址相同的结点之后的所有结点的内存空间释放掉
}

void ModfiyInfo(PLRPIN *Info) //修改信息
{
    char cName[24];
    char cYesNo;
    PLRPIN Current;

    printf("请输入要修改名片的姓名:");
    scanf("%s", cName);
    printf("确定要修改 %s 信息吗?(Y/N):", cName);

    do
    {
        cYesNo = getchar();
    } while (cYesNo != 'Y' && cYesNo != 'N');

    if (cYesNo == 'Y')
    {
        Current = *Info;

        while (Current != NULL && Current->name == cName) //搜查符合的条件
        {
            Current = Current->next;
        }
        if (Current == NULL)
        {
            printf("没有找到要修改的名片,请确认您的输入!\n");
            return;
        }
        else
        {
            printf("找到匹配:%s %s %s\n", Current->name, Current->beizhu, Current->number);
            printf("将%s修改为:", Current->name);
            scanf("%s", Current->name);

            printf("将%s修改为:", Current->beizhu);
            scanf("%s", Current->beizhu);

            printf("将%s修改为:", Current->number);
            scanf("%s", Current->number);
            printf("修改后的信息为:%s %s %s\n", Current->name, Current->beizhu, Current->number);
            printf("修改成功!\n");
        }
    }
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-25 17:08:28 | 显示全部楼层
黄翼 发表于 2020-2-23 23:36
您帮我测试一下,第二次调用查找函数就出错什么原因呢?

第二次调用查找函数出错是因为你第一次掉的时候查找函数最后的releaseInfo(New)把链表中的一部分结点删掉了,导致数据结构被破坏。New的前一个结点的next不等于Null,但是其指向的结点New已经吧free掉了。
具体看我在6楼的回复
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-2 19:12:48 | 显示全部楼层
major_lyu 发表于 2020-2-25 17:08
第二次调用查找函数出错是因为你第一次掉的时候查找函数最后的releaseInfo(New)把链表中的一部分结点删掉 ...

谢谢哈
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-15 23:23

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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