c语言txt文件乱码

保存好的文件是乱码
问题相关代码,请勿粘贴截图
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
 
 
typedef struct person
{
    char name[20]; //姓名
    char num[20];//手机号
    char email[20];//邮箱
} PER;
 
 
int menu();//选择界面
void add_person(PER arr[],int *nPtr);//添加
void InputPerson(PER arr[],int i);         
void OutPerson(PER arr[],int i);         
int print_person(PER arr[],int n);     
int FindByName(PER arr[],int n,char *str);//查询
void search_person_name(PER arr[],int n);   
void delete_person(PER arr[],int *nPtr);//删除
void modify_person(PER arr[],int n);//修改
void save_file(PER arr[],int n);//保存
void load_file(PER arr[],int *nPtr);      


int main()
{
    system("color 02");
    SetConsoleTitle("通讯录");
    PER per[100];
    int choice;
    int n;
    load_file(per,&n);
    while(1)
    {
        choice = menu();
        switch(choice)
        {
        case 1:         //添加
            add_person(per,&n); break;
        case 2:         //删除
            delete_person(per,&n);break;
        case 3:               //查询
            search_person_name(per,n);break;        
        case 4:             //修改
            modify_person(per,n);break;
        case 5:         //显示
           print_person(per,n);break;
        case 7:
            //显示
           save_file(per,n);break;
        case 6:         //退出
            printf("\t 谢谢使用\n");
            return 0;
        }
    }
 
}
int menu()//菜单
{
    int choise;
    system("cls");
    system("color 0F");
        printf("\t\t\t\t|========== 欢迎使用通讯录=========|\n");
        printf("\t\t\t\t|              1--添加           |\n");
        printf("\t\t\t\t|              2--删除           |\n");
        printf("\t\t\t\t|              3--查询           |\n");
        printf("\t\t\t\t|              4--修改           |\n");
        printf("\t\t\t\t|              5--显示           |\n");
        printf("\t\t\t\t|              6--退出           |\n");
        printf("\t\t\t\t|              7--保存           |\n");
        printf("\t\t\t\t|==================================|\n");
    printf("\t\t\t\t您的选择是: ");
    scanf("%d",&choise);
    while(choise>7||choise<0)
    {
        printf("请重新选择:");
        scanf("%d",&choise);
    }
    return choise;
}
void load_file(PER arr[],int *nPtr)     
{
    FILE *fp;
    int i;
 
    if((fp=fopen("num.txt","w"))==NULL)
    {
        *nPtr = 0;
        return;
    }
    for(i=0;fread(&arr[i],sizeof(PER),1,fp)!=0;i++);
    *nPtr = i;  
}
void save_file(PER arr[],int n)          //保存
{
    FILE *fp;
    if((fp=fopen("num.txt","w"))==NULL)
    {
        printf("打开文件失败\n");
        system("pause");
        exit(0);
    }
 
    fwrite(arr,n * sizeof(arr[0]),1,fp);
    fclose(fp);
}
int print_person(PER arr[],int n)        //显示
{
    int i;
    printf("%-15s%-15s%-15s%\n","姓名","手机号","邮箱");
 
    for(i=0;i<n;i++)
    {
        OutPerson(arr,i);
    }
    system("pause");
    return 0;
}
void add_person(PER arr[],int *nPtr)    //添加
{
    char sel = 'y';
 
    while(sel=='y')
    {
        InputPerson(arr,(*nPtr)++);   
        printf("是否继续添加联系人?(y,n)\n");
        scanf(" %c",&sel);
    }
    save_file(arr,*nPtr);
    printf("添加结束\n");
    system("pause");
}
void InputPerson(PER arr[],int i)      
{
    printf("请输入第%d个联系人\n",i+1);
 
    printf("请输入联系人姓名\n");
    scanf("%s",arr[i].name); 
    printf("请输入联系人手机号\n");
    scanf("%s",arr[i].num);
    printf("请输入联系人邮箱\n");
    scanf("%s",arr[i].email);
}
void OutPerson(PER arr[],int i)        
{
    printf("%-15s",arr[i].name);
    printf("%-15s",arr[i].num);
    printf("%-15s",arr[i].email);
    printf("\n");
}

void delete_person(PER arr[],int *nPtr)     //删除
{
    int i,index;
    char str[20];
 
    printf("请输入删除联系人的姓名");
    scanf("%s",str);
    index = FindByName(arr,*nPtr,str);
 
    if(index<0)
    {
        printf("\n 该联系人不存在\n");
        system("pause");
        return ;
    }
    for(i=index;i<*nPtr-1;i++)
        arr[i]=arr[i+1];
 
    (*nPtr)--;
 
    printf("\n 删除成功\n");
    system("pause");
    save_file(arr,*nPtr);
}

void  modify_person(PER arr[],int n)         //修改
{
    int index;
    char sel;
    char str[20];
    printf("请输入姓名:\n");
    scanf("%s",str);
    index = FindByName(arr,n,str);
 
    if(index<0)
    {
        printf("该联系人信息不存在\n");
        system("pause");
        return ;
    }
    printf("修改前的原纪录如下:\n");
    OutPerson(arr,index);
 
    printf("是否修改姓名(y/n):\n");
    scanf(" %c",&sel);
    if(sel =='y')
    {
        printf("请输入姓名:\n");
        scanf("%s",arr[index].name);
    }
    printf("是否修改手机号:\n");
    scanf(" %c",&sel);
    if(sel =='y')
    {
        printf("请输入新的手机号:\n");
        scanf("%s",arr[index].num);
    }
    printf("是否修改邮箱:\n");
    scanf(" %c",&sel);
    if(sel =='y')
    {
        printf("请输入新的邮箱:\n");
        scanf("%s",arr[index].email);
    }
    save_file(arr,n);
    system("pause");
}
void search_person_name(PER arr[],int n)    //查询
{
    int index;
    char str[20];
    printf("请输入查找的联系人姓名");
    scanf("%s", str);
 
    index=FindByName(arr,n,str);
 
    if(index<0)
    {
        printf("该联系人不存在");
        system("pause");
        return ;
    }
    printf("%-15s%-15s%-15s%\n","姓名","手机号","邮箱");
    OutPerson(arr,index);
    system("pause");
}
int FindByName(PER arr[],int n,char *str)  
{
    int i;
 
    for (i=0;i<n;i++)
        if(strcmp(arr[i].name,str)==0)
        return i;
    return -1;
}


运行结果及报错内容

img

我的解答思路和尝试过的方法

txt的编码是ANSI

我想要达到的结果

修改处见注释,供参考:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
typedef struct person
{
    char name[20]; //姓名
    char num[20];//手机号
    char email[20];//邮箱
}PER;


int menu();//选择界面
void add_person(PER arr[],int *nPtr);//添加
void InputPerson(PER arr[],int i);
void OutPerson(PER arr[],int i);
int print_person(PER arr[],int n);
int FindByName(PER arr[],int n,char *str);//查询
void search_person_name(PER arr[],int n);
void delete_person(PER arr[],int *nPtr);//删除
void modify_person(PER arr[],int n);//修改
void save_file(PER arr[],int n);//保存
void load_file(PER arr[],int *nPtr);


int main()
{
    system("color 02");
    SetConsoleTitle("通讯录");
    PER per[100];
    int choice;
    int n;
    load_file(per,&n);
    while(1)
    {
        choice = menu();
        switch(choice)
        {
        case 1:         //添加
            add_person(per,&n); break;
        case 2:         //删除
            delete_person(per,&n);break;
        case 3:               //查询
            search_person_name(per,n);break;        
        case 4:             //修改
            modify_person(per,n);break;
        case 5:         //显示
           print_person(per,n);break;
        case 7:
            //显示
           save_file(per,n);break;
        case 6:         //退出
            printf("\t 谢谢使用\n");
            return 0;
        }
    }
 
}
int menu()//菜单
{
    int choise;
    system("cls");
    system("color 0F");
        printf("\t\t\t\t|========== 欢迎使用通讯录=========|\n");
        printf("\t\t\t\t|              1--添加           |\n");
        printf("\t\t\t\t|              2--删除           |\n");
        printf("\t\t\t\t|              3--查询           |\n");
        printf("\t\t\t\t|              4--修改           |\n");
        printf("\t\t\t\t|              5--显示           |\n");
        printf("\t\t\t\t|              6--退出           |\n");
        printf("\t\t\t\t|              7--保存           |\n");
        printf("\t\t\t\t|==================================|\n");
    printf("\t\t\t\t您的选择是: ");
    scanf("%d",&choise);
    while(choise>7||choise<0)
    {
        printf("请重新选择:");
        scanf("%d",&choise);
    }
    return choise;
}
void load_file(PER arr[],int *nPtr)
{
    FILE *fp;
    int i;
    //if((fp=fopen("num.txt","w"))==NULL)修改
    if((fp=fopen("num.txt","r"))==NULL)
    {
        *nPtr = 0;
        return;
    }
    //for(i=0;fread(&arr[i],sizeof(PER),1,fp)!=0;i++); 修改
    for(i=0;fscanf(fp,"%s %s %s\n",arr[i].name,arr[i].num,arr[i].email)==3;i++);
    *nPtr = i;
    fclose(fp); //修改
}
void save_file(PER arr[],int n)          //保存
{
    int i;
    FILE *fp;
    if((fp=fopen("num.txt","w"))==NULL)
    {
        printf("打开文件失败\n");
        system("pause");
        exit(0);
    }
    //fwrite(arr,sizeof(PER),n,fp);     修改
    //fwrite(arr,n * sizeof(arr[0]),1,fp);
    for(i=0;i<n;i++)
        fprintf(fp,"%s %s %s\n",arr[i].name,arr[i].num,arr[i].email);
    fclose(fp);
}
int print_person(PER arr[],int n)        //显示
{
    int i;
    printf("%-15s%-15s%-15s\n","姓名","手机号","邮箱");
    //printf("%-15s%-15s%-15s%\n","姓名","手机号","邮箱"); 修改
    for(i=0;i<n;i++)
    {
        OutPerson(arr,i);
    }
    system("pause");
    return 0;
}
void add_person(PER arr[],int *nPtr)    //添加
{
    char sel = 'y';
 
    while(sel=='y')
    {
        InputPerson(arr,(*nPtr)++);   
        printf("是否继续添加联系人?(y,n)\n");
        scanf(" %c",&sel);
    }
    save_file(arr,*nPtr);
    printf("添加结束\n");
    system("pause");
}
void InputPerson(PER arr[],int i)      
{
    printf("请输入第%d个联系人\n",i+1);
 
    printf("请输入联系人姓名\n");
    scanf("%s",arr[i].name); 
    printf("请输入联系人手机号\n");
    scanf("%s",arr[i].num);
    printf("请输入联系人邮箱\n");
    scanf("%s",arr[i].email);
}
void OutPerson(PER arr[],int i)        
{
    printf("%-15s",arr[i].name);
    printf("%-15s",arr[i].num);
    printf("%-15s",arr[i].email);
    printf("\n");
}
 
void delete_person(PER arr[],int *nPtr)     //删除
{
    int i,index;
    char str[20];
 
    printf("请输入删除联系人的姓名");
    scanf("%s",str);
    index = FindByName(arr,*nPtr,str);
 
    if(index<0)
    {
        printf("\n 该联系人不存在\n");
        system("pause");
        return ;
    }
    for(i=index;i<*nPtr-1;i++)
        arr[i]=arr[i+1];
 
    (*nPtr)--;
 
    printf("\n 删除成功\n");
    system("pause");
    save_file(arr,*nPtr);
}
 
void  modify_person(PER arr[],int n)         //修改
{
    int index;
    char sel;
    char str[20];
    printf("请输入姓名:\n");
    scanf("%s",str);
    index = FindByName(arr,n,str);
 
    if(index<0)
    {
        printf("该联系人信息不存在\n");
        system("pause");
        return ;
    }
    printf("修改前的原纪录如下:\n");
    OutPerson(arr,index);
 
    printf("是否修改姓名(y/n):\n");
    scanf(" %c",&sel);
    if(sel =='y')
    {
        printf("请输入姓名:\n");
        scanf("%s",arr[index].name);
    }
    printf("是否修改手机号:\n");
    scanf(" %c",&sel);
    if(sel =='y')
    {
        printf("请输入新的手机号:\n");
        scanf("%s",arr[index].num);
    }
    printf("是否修改邮箱:\n");
    scanf(" %c",&sel);
    if(sel =='y')
    {
        printf("请输入新的邮箱:\n");
        scanf("%s",arr[index].email);
    }
    save_file(arr,n);
    system("pause");
}
void search_person_name(PER arr[],int n)    //查询
{
    int index;
    char str[20];
    printf("请输入查找的联系人姓名");
    scanf("%s", str);
 
    index=FindByName(arr,n,str);
 
    if(index<0)
    {
        printf("该联系人不存在");
        system("pause");
        return ;
    }
    printf("%-15s%-15s%-15s%\n","姓名","手机号","邮箱");
    OutPerson(arr,index);
    system("pause");
}
int FindByName(PER arr[],int n,char *str)  
{
    int i;
 
    for (i=0;i<n;i++)
        if(strcmp(arr[i].name,str)==0)
        return i;
    return -1;
}

fwrite(arr,n * sizeof(arr[0]),1,fp);第二个参数是单位内容大小,你要一次全写入这样写
fwrite(arr,sizeof(arr[0]),n,fp);,第三个次数表示读取个数

你保存的时候可以设置字符编码。
你电脑也是有字符编码的,你保存文件的字符编码要和你电脑的字符编码兼容才能正确显示。