为什么运行出来无法实现从文件读取数据,且再次存储数据时以前数据会出现乱码
#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个联系人。注意,在从标准输入中读取字符串时,需要处理多余的换行符。