C语言个人通讯录程序

为什么运行出来无法实现从文件读取数据,且再次存储数据时以前数据会出现乱码

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

/******函数声明******/
///////////////////////////////
//主业务
///////////////////////////////
//增加:
void addStudent();
//删除:
void deleteStudent();
//查找;
void queryBySno();
void queryByName();
void queryStudent();
//修改:
void updateStudent();
//打印所有信息:
void printAll();
//系统分析:
void analysis();
///////////////////////////////
//辅助业务 
///////////////////////////////
//读文件
int readData();
//写文件
int writeData();
//自动生成学号
int createSno();
//根据学号找索引:
int findIndex(int sno);
//显示当前学生信息
void printCurrent(int index);
//欢迎界面
void welcome();
//主菜单
void mainMenu();
 
//定义结构体
struct student
{

  int sno;//学号
  char name[20];
  char sex[3];
  char  major[50];
  char class[10];
  int room;
  char native[50];
  long long number;
  long long qqnumber;
  char wechat[50];
  int state;
  
};
//定义结构体数组存储信息
struct student students[100];
//定义储存当前最大的索引
int maxIndex = -1;
//定义文件指针,操作文件 
FILE *fp ;
/**********主函数************/ 
int main(int argc, char *argv[]) {
    welcome();
    maxIndex = readData();
    mainMenu();
    return 0;
}
/************函数定义  *****************/
/************主菜单   *****************/ 
void mainMenu(){
    //循环显示主业务
    //提供选择项体式
    //根据输入选择项后调用主业务函数
    int select = 0;
    while(1){
        printf("|-------------------------------------------------------|\n");
        printf("|                 1. 增加通讯录信息                     |\n");
        printf("|                 2. 删除通讯录信息                     |\n");
          printf("|                 3. 修改通讯录信息                     |\n");
        printf("|                 4. 查询通讯录信息                     |\n");
        printf("|                 5. 打印通讯录信息                     |\n");
        printf("|                 0. 退出系统                           |\n");    
        printf("|-------------------------------------------------------|\n");
        printf("请选择业务:"); 
        scanf("%d",&select); 
        switch(select) 
        {
            case 1:
                addStudent();
                break;
            case 2:
                deleteStudent();
                break;
            case 3:
                updateStudent();
                break;
            case 4:
                queryStudent();
                break;
            case 5:
                printAll();
                break;
            case 0:
                exit(0);
                default:
                    printf("您的选择有误,请重新选择"); 
                
        }
    }
}

/************ 主要业务 *****************/ 
/*****************************************

******************************************/
void addStudent(){
    char answer = 'n';
    printf("|------------------ 增加通讯录信息 ------------------|\n");
    //输入数据到数组
    maxIndex ++; 
    //给学生信息赋值
    while(1){    
    students[maxIndex].sno = createSno();
    //写文件 
    fflush(stdin);//清空缓存 
    printf("姓名:");
    gets(students[maxIndex].name); 
    fflush(stdin);
    printf("性别:");
    gets(students[maxIndex].sex); 
    fflush(stdin);
    printf("专业:");
    gets(students[maxIndex].major); 
    fflush(stdin);
    printf("班级:");
    gets(students[maxIndex].class); 
    fflush(stdin);
    printf("宿舍号:");
    scanf("%d",&students[maxIndex].room); 
    fflush(stdin);
    printf("籍贯:");
    gets(students[maxIndex].native); 
    fflush(stdin);
    printf("手机号:");
    scanf("%lld",&students[maxIndex].number); 
    fflush(stdin);
    printf("QQ号:");
    scanf("%lld",&students[maxIndex].qqnumber); 
    fflush(stdin); 
    printf("微信号:");
    gets(students[maxIndex].wechat);
    //状态 默认置为1
     students[maxIndex].state = 1; 
     //写文件 
     if(writeData() == 1) 
     {
         printf("增加成功!\n");
     }else{
         printf("增加失败!\n");
     }
     printf("是否继续:是(y)否(n):");
     fflush(stdin);
     scanf("%c",&answer); 
     if(answer=='y'){
         continue;
     }else{
         break;
     }
  }
}
/**********************************************
函数功能:删除通讯录中的信息,将通讯录状态置位0 
参数:无
返回值:无 
***********************************************/
void deleteStudent(){
    printf("|------------------ 删除通讯录信息 ------------------|\n");
    int sno;
    int index=-1;
    int answer = 0;
    printf("请输入要删除的同学学号:\n");
    scanf("%d",&sno);
    //根据学号查找学生
    index = findIndex(sno);
    if(index==-1){
        printf("没有该同学信息\n");
        return;//当1前函数结束,后续不再执行,返回被调用处 
    }
    //如果找到打印当前学生信息
    printCurrent(index); 
    printf("您确定要删除吗? 1是 0否\n");
    scanf("%d",&answer);
    if(answer==1){
        //当前学生的状态置位0
        students[index].state =0;
        //重新写文件 
        //写文件
     if(writeData() == 1) 
     {
         printf("删除成功!\n");
     }else{
         printf("删除失败!\n");
     }
    }
     
}
void queryBySno(){
    int sno;
    int index =-1;
    printf("请输入学号:\n");
    scanf("%d",&sno);
    index = findIndex(sno);
    if(index==-1){
        printf("没有该信息\n");
    }else{
        printCurrent(index);
    } 
}
/**********************************************
函数功能:查询通讯录信息,根据姓名关键字查询 
参数:无
返回值:无 
***********************************************/
//strstr(s1,s2) 从s1中查找是否包含s2 
void queryByName(){
    char name[10];
    int index=-1;
    int i = 0;
    int flag = 0;
    printf("请输入姓名:\n");
    fflush(stdin);
    gets(name);
    //遍历数组
    for(i=0;i<=maxIndex;i++){ 
        if(students[i].state==1){
            if(strstr(students[i].name,name) != NULL){
                flag=1;
                printCurrent(i);
            }
        }
    } 
    if(flag==0){
        printf("没有该信息!\n"); 
    }
}
/**********************************************
函数功能:查询通讯录信息,先根据学号和姓名查找,
找到后打印 
参数:无
返回值:无 
***********************************************/
void queryStudent(){
    int select=0; 
    printf("|------------------ 查询通讯录信息 ------------------|\n");
    printf("|            1 按学号                2 按姓名        |\n");
    scanf("%d",&select);
    if(select==1){
        //按学号查找 
        queryBySno();
    }else{
        //按姓名
        queryByName(); 
    }
}
/**********************************************
函数功能:修改学生信息,先根据学号查找,找到后
重新输入学生数据,再写文件 
参数:无
返回值:无 
***********************************************/
void updateStudent(){
    int sno;
    int index;
    printf("|------------------ 修改通讯录信息 ------------------|\n");
    printf("请输入要修改的同学学号:\n");
    scanf("%d",&sno);
    //根据学号查找学生
    index = findIndex(sno);
    if(index==-1){
        printf("没有该同学信息\n");
        return;//当1前函数结束,后续不再执行,返回被调用处 
    }
    //如果找到,打印当前学生信息
    printCurrent(index);
    //重新输入 
    fflush(stdin);//清空缓存 
    printf("姓名:");
    gets(students[index].name); 
    fflush(stdin);
    printf("性别:");
    gets(students[index].sex); 
    fflush(stdin);
    printf("专业:");
    gets(students[index].major); 
    fflush(stdin);
    printf("班级:");
    gets(students[index].class); 
    fflush(stdin);
    printf("宿舍号:");
    scanf("%d",&students[index].room); 
    fflush(stdin);
    printf("籍贯:");
    gets(students[index].native); 
    fflush(stdin);
    printf("手机号:");
    scanf("%lld",&students[index].number); 
    fflush(stdin);
    printf("QQ号:");
    scanf("%lld",&students[index].qqnumber); 
    fflush(stdin); 
    printf("微信号:");
    gets(students[index].wechat); 
     //写文件
     if(writeData() == 1) 
     {
         printf("修改成功!\n");
     }else{
         printf("修改失败!\n");
}
}
/***************************************
函数功能:打印数组中实际存在的信息
参数:无
返回值:无 
***************************************/
void printAll(){
    int i=0;
    printf("|------------------ 打印通讯录信息 ------------------|\n");
    printf("|----------------------------------------------------------------------------------------------------------------------------|\n"); 
    printf("|%-8s|%-10s|%-8s|%-8s|%-8s|%-8s|%-16s|%-16s|%-16s|%-16s|\n","学号","姓名","性别","专业","班级","宿舍号","籍贯","手机号","QQ号","微信号"); 
    printf("|--------+----------+--------+--------+--------+--------+----------------+----------------+-----------------+----------------|\n");
    //循环打印
    for(i=0;i<=maxIndex;i++){
        if(students[i].state==1){
         printf("|%-8d|%-10s|%-8s|%-8s|%-8s|%-8d|%-16s|%-16lld|%-16lld|%-16s|\n",
          students[i].sno,
         students[i].name,
         students[i].sex,
         students[i].major,
         students[i].class,
         students[i].room,
         students[i].native,
         students[i].number,
         students[i].qqnumber,
         students[i].wechat);
         if(i<maxIndex){
             printf("|--------+----------+--------+--------+--------+--------+----------------+----------------+-----------------+----------------|\n");
         }
         else{ 
            printf("|----------------------------------------------------------------------------------------------------------------------------|\n"); 
        }
    }
}
}

/*************** 辅助业务 *****************/ 
/*****************************************
函数功能:读文件,将磁盘上的数据读到数组中
          只在运行中读一次 
参数:无(用的全局变量) 
返回值:返回读取到数据的最大索引,如果是第
一次运行需要创建文件 并返回-1 
******************************************/
int readData(){
    //记录读取文件的行数 
    int i =0;
    //以读的方式打开文件 
    //1 打开文件
    if((fp = fopen("studentInfo.txt","r")) == NULL){
        //创建新文件 
        fp = fopen("studentInfo.txt","w");
        return -1;
    }
    
    //2 读文件
    /*while(feof(fp)!=1)//end of 文件最后 
    {
        fscanf(fp,"%d %s %s %s %s %d %s %lld %lld %s %d",
         &students[i].sno,
         students[i].name,
         students[i].sex,
         students[i].major,
         &students[i].class,
         &students[i].room,
         students[i].native,
         &students[i].qqnumber,
         students[i].wechat,
         &students[i].state); 
         //格式读写,根据存储的数据顺序依次读入 
        //学号,姓名,性别,专业,班级,宿舍号,籍贯,手机号,qq号,微信号 
        //读取一行数据所以加一 
        i++;
    } */
    while(!feof(fp)){
    fread(&students[i],sizeof(struct student),1,fp);
    if(students[i].state==0){
        break;
    }else{
        i++;
    }
}
    //3 关闭文件 
    fclose(fp); 
    return i;
    //多读取一个空行,索引从0开始 
    //return i-2;
}
/*****************************************
函数功能:写文件,将数组中的数据写到磁盘上的文件中
          增删改操作都需要进行写文件 
参数:无(用的全局变量) 
返回值:写文件成功返回1,失败返回0 
******************************************/
int writeData(){
    //数组索引 
    int i =0;
    //1 打开文件
    if((fp=fopen("studentInfo.txt","w")) == NULL){
        printf("打开文件失败");
        return 0;
    }
    //2 写文件 -遍历数组循环操作
    for(i=0;i<=maxIndex;i++){
        fprintf(fp,"%d %s %s %s %s %d %s %lld  %lld %s %d\n",
         students[i].sno,
         students[i].name,
         students[i].sex,
         students[i].major,
         students[i].class,
         students[i].room,
         students[i].native,
         students[i].number,
         students[i].qqnumber,
         students[i].wechat,
         students[i].state);
         
    } 
    
    //3 关闭文件 
    fclose(fp);
    return 1;
    
}
/*****************************************
函数功能:自动生成学号,如果是第一个学生学号是10001
否则返回上一个学生的学号加一 
即上一个学生的学号加一--students[maxIndex-1] .sno+1         
参数:无
返回值:学号 
******************************************/
int createSno(){
    if(maxIndex==0){
        return 10001;
    } else{
        //上一个学生的学号加一 
        return students[maxIndex -1].sno +1;
    }
}
/*****************************************
函数功能:根据学号查找索引        
参数: 学生的学号 
返回值:该学号学生在数组中的索引,如果找到了
返回索引,否则返回-1 
******************************************/
int findIndex(int sno) {
    int index = -1;
    int i =0;
    for(i=0;i<=maxIndex;i++){
        //保证联系人存在 
        if(students[i].state==1) {
        
        if(students[i].sno == sno){
            //记录当前索引 
            index = i;
            break; 
        }
    }
    } 
    return index;
}
/*****************************************
函数功能:打印当前索引的信息    
参数: 数组中的索引 
返回值: 无 
******************************************/
void printCurrent(int index){
    printf("|----------------------------------------------------------------------------------------------------------------------------|\n"); 
    printf("|%-8s|%-10s|%-8s|%-8s|%-8s|%-8s|%-16s|%-16s|%-16s|%-16s|\n","学号","姓名","性别","专业","班级","宿舍号","籍贯","手机号","QQ号","微信号"); 
    printf("|--------+----------+--------+--------+--------+--------+----------------+----------------+-----------------+----------------|\n");
    printf("|%-8d|%-10s|%-8s|%-8s|%-8s|%-8d|%-16s|%-16lld|%-16lld|%-16s|\n",
          students[index].sno,
         students[index].name,
         students[index].sex,
         students[index].major,
         students[index].class,
         students[index].room,
         students[index].native,
         students[index].number,
         students[index].qqnumber,
         students[index].wechat);
    printf("|----------------------------------------------------------------------------------------------------------------------------|\n");
    printf("\n"); 
}
void welcome(){
    printf("|-------------------------------------------------------|\n");
    printf("|------------  欢迎使用个人通讯录管理系统  -------------|\n"); 
    printf("|-------------------------------------------------------|\n");
    printf("\n");
}

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

#define MAX_CONTACTS 100

struct contact {
    char name[50];
    char phone_number[20];
    char email[50];
};

struct contact contacts[MAX_CONTACTS];
int num_contacts = 0;

void add_contact() {
    if (num_contacts == MAX_CONTACTS) {
        printf("通讯录已满,无法添加新的联系人。\n");
        return;
    }
    struct contact new_contact;
    printf("请输入联系人姓名:");
    fgets(new_contact.name, 50, stdin);
    new_contact.name[strcspn(new_contact.name, "\n")] = '\0'; // 删除换行符
    printf("请输入联系人电话号码:");
    fgets(new_contact.phone_number, 20, stdin);
    new_contact.phone_number[strcspn(new_contact.phone_number, "\n")] = '\0';
    printf("请输入联系人电子邮箱:");
    fgets(new_contact.email, 50, stdin);
    new_contact.email[strcspn(new_contact.email, "\n")] = '\0';
    contacts[num_contacts++] = new_contact;
    printf("联系人已添加到通讯录。\n");
}

void list_contacts() {
    printf("所有联系人:\n");
    for (int i = 0; i < num_contacts; i++) {
        printf("姓名:%s,电话:%s,电子邮箱:%s\n",
            contacts[i].name, contacts[i].phone_number, contacts[i].email);
    }
}

void search_contacts() {
    char query[50];
    printf("请输入要查询的联系人姓名:");
    fgets(query, 50, stdin);
    query[strcspn(query, "\n")] = '\0'; // 删除换行符
    for (int i = 0; i < num_contacts; i++) {
        if (strcmp(contacts[i].name, query) == 0) {
            printf("查询结果:姓名:%s,电话:%s,电子邮箱:%s\n",
                contacts[i].name, contacts[i].phone_number, contacts[i].email);
            return;
        }
    }
    printf("未找到匹配的联系人。\n");
}

int main() {
    int choice;
    while (1) {
        printf("\n请选择要执行的操作:\n");
        printf("1. 添加联系人\n");
        printf("2. 列出所有联系人\n");
        printf("3. 查询联系人\n");
        printf("4. 退出程序\n");
        printf("请输入操作序号:");
        scanf("%d", &choice);
        getchar(); // 处理多余的换行符
        switch (choice) {
            case 1:
                add_contact();
                break;
            case 2:
                list_contacts();
                break;
            case 3:
                search_contacts();
                break;
            case 4:
                printf("程序已退出。\n");
                exit(0);
            default:
                printf("无效的操作序号,请重新输入。\n");
                break;
        }
    }
    return 0;
}

这个程序允许用户添加联系人、列出所有联系人、查询联系人等操作,最多可以添加100个联系人。注意,在从标准输入中读取字符串时,需要处理多余的换行符。