#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<dos.h>
#include<string.h>
#include<Windows.h>
#include<stdarg.h>
struct Student {
char name[10];//定义学生名字
char sno[13];//定义学生学号
char gender[10];//定义学生性别
char fromPlace[9];//定义学生生源地
char phone[12];//定义学生电话号码
};
struct Student stu;
struct Student studinfos[150];
int TotalCount = 0;
void in();//定义输入函数
void show();//定义查找函数
void showgender();//定义查看性别函数
void showfromplace();//定义查看生源地函数
int main(int argc, char* argv[]) {
int n;
//主菜单
while (1) {
printf_s("\t************************\n");
printf_s("\t* 学生信息管理系统 *\n");
printf_s("\t* 主菜单 *\n");
printf_s("\t* 1 输入学生信息 *\n");
printf_s("\t* 2 查找学生信息 *\n");
printf_s("\t* 3 学生性别占比 *\n");
printf_s("\t* 4 统计学生信息 *\n");
printf_s("\t* 0 退出系统 *\n");
printf_s("\t************************\n");
printf_s("\n");
printf_s("请输入选择的功能(1-0):\n");
scanf_s("%d", &n);
switch (n) {
case 0: {
printf_s("感谢您的使用,再见!\n");
return 0;
break;
}
case 1: {
in();
break;
}
case 2: {
show();
break;
}
case 3: {
showgender();
break;
}
case 4: {
showfromplace();
break;
}
}
}
printf("请输入选择的功能:\n");
return 0;
}
//输入函数
void in()
{
FILE* fp;
char yn = 'y';
if ((fp = fopen("C:\\Users\\ALIENWARE\\Desktop\\student.txt", "a+")) != NULL)//以a模式打开文件
{
while (yn == 'y')
{
printf_s("请输入学生信息\n");
printf_s("请输入姓名\n");
scanf_s("%s", stu.name, 8);
stu.name[8] = '\0';
printf_s("请输入学号\n");
scanf_s("%s", stu.sno, 12);
stu.sno[12] = '\0';
printf_s("请输入性别\n");
scanf_s("%s", stu.gender, 10);
stu.gender[9] = '\0';
printf_s("请输入生源地\n");
scanf_s("%s", stu.fromPlace, 8);
stu.fromPlace[8] = '\0';
printf_s("请输入手机号码\n");
scanf_s("%s", stu.phone, 11);
stu.phone[11] = '\0';
printf_s("姓名:%-8s 学号:%-12s 性别:%-9s 生源地:%-8s 手机号:%-11s\n", stu.name, stu.sno, stu.gender, stu.fromPlace, stu.phone);
fprintf_s(fp, "%s,%s,%s,%s,%s\n", stu.name, stu.sno, stu.gender, stu.fromPlace, stu.phone);
fflush(fp);//把文件缓冲区的内容写入磁盘
fflush(stdin);//清除键盘缓存内容
int y = getchar();
printf_s("是否继续输入学生信息(y/n)\n");
scanf_s("%c", &yn, 2);
}
fclose(fp);
}
else {
printf_s("文件打开错误!");
}
}
//查找函数
void show()
{
FILE* fp;
int stupos = 0;
fp = fopen("students.txt", "r");
printf_s("%-8s %-12s %-9s %-8s %-11s\n", "姓名", "学号", "性别", "生源地", "手机号码");
if (!fp)
return;
while (fread(&studinfos[stupos], sizeof(struct Student), 1, fp) != NULL)
{
if (studinfos[stupos].name[0] != '\0')
{
studinfos[stupos].name[8] = '\0';
studinfos[stupos].sno[12] = '\0';
studinfos[stupos].gender[9] = '\0';
studinfos[stupos].fromPlace[8] = '\0';
studinfos[stupos].phone[11] = '\0';
printf_s("%-8s %-12s %-9s %-8s %-11s\n", studinfos[stupos].name, studinfos[stupos].sno, studinfos[stupos].gender, studinfos[stupos].fromPlace, studinfos[stupos].phone);
}
}
fclose(fp);
}
//查看性别函数
void showgender() {
int male = 0, female = 0, error = 0;
int stupos = 0;
int i;
FILE* fp = NULL;
if ((fp = fopen("C:\\Users\\ALIENWARE\\Desktop\\student.txt", "r+")) == NULL) {
printf_s("文件不存在!");
}
while (!feof(fp))/*文本结束,返回非零值 */ {
if (fread(&studinfos[stupos], sizeof(struct Student), 1, fp) == 1) {
stupos++;
}
}
if (stupos == 0) {
printf_s("文件没有内容!\n");
fclose(fp);
return;
}
else {
printf_s("这个班的学生有%d名学生。\n", stupos);
fclose(fp);
}
for (i = 0; i < stupos; i++) {
studinfos[i].gender[10] = '\0';
if (strncmp(studinfos[i].gender, "m", 10) == 0) {
male++;
}
else if (strncmp(studinfos[i].gender, "f", 10) == 0) {
female++;
}
else {
error++;
}
}
printf_s("男生占比%4.2f\n\n", (male * 1.0 / stupos));
printf_s("女生占比%4.2f\n\n", (female * 1.0 / stupos));
}
//定义查看生源地函数
void showfromplace(){
FILE* fp;
int stupos = 0;
int Totalcounts;
fp = fopen("students.txt", "r");
if (!fp)
return;
while (fread(&studinfos[stupos], sizeof(struct Student), 1, fp) != NULL)
{
if (studinfos[stupos].name[0] != '\0')
{
studinfos[stupos].name[8] = '\0';
studinfos[stupos].sno[12] = '\0';
studinfos[stupos].gender[2] = '\0';
studinfos[stupos].fromPlace[8] = '\0';
studinfos[stupos].phone[11] = '\0';
printf("%-8s %-12s %-2s %-8s %-11s\n",studinfos[stupos].name,studinfos[stupos].sno,studinfos[stupos].gender,studinfos[stupos].fromPlace,studinfos[stupos].phone);
}
stupos++;//下标位置加1
}
Totalcounts = stupos;
struct PlaceCount
{
char place[9]; //生源地
int count; //该生源地的人数
};
struct PlaceCount placecounts[Totalcounts]; //创建一个结构体数组,每个元素包含一个char类型的place和int类型的count
int i;
for (i = 0; i < Totalcounts; i++) { //初始化结构体数组
placecounts[i].place[0] = '0';
placecounts[i].count = 0;
}
for (i = 0; i < Totalcounts; i++) //将studinfos结构体数组中的每个fromPlace拷贝到placecounts结构体数组中
{
strcpy(placecounts[i].place, studinfos[i].fromPlace);
}
int outer, inner;
struct PlaceCount tmp;//定义一个结构体变量用来交换
for (outer = 0; outer < Totalcounts - 1; outer++) {
//采用冒泡排序的方法将结构体数组按palce的大小进行排序
for (inner = 0; inner < Totalcounts - outer - 1; inner++) {
if (strcmp(placecounts[inner].place, placecounts[inner + 1].place) > 0)
{
tmp = placecounts[inner]; //创建临时变量tmp,用于交换前后两个元素的位置
placecounts[inner] = placecounts[inner + 1];
placecounts[inner + 1] = tmp;
}
}
}
for (i = 0; i < Totalcounts; i++)
{
printf("%s\n", placecounts[i].place);
}
int marks = 0;
for (i = 0; i < Totalcounts; i++) //统计相同生源地的个数
{
if (strcmp(placecounts[i].place, placecounts[marks].place) == 0)
{//将已经排序好的结构体数组中的place元素进行比较,用marks=0作为起点,
//让它与后面的每一个生源地进行比较看是否相同,相同则那一生源地数目加1,
//i递增,marks不变,不同则将i赋值给marks,作为新起点与后面的生源地进行比较
placecounts[marks].count++;
}
else {
marks = i;
placecounts[marks].count++;
}
}
int m;
for (i = 0; i < Totalcounts; i++)
{
if (placecounts[i].count > 0) //避免重复打印相同的生源地
{
printf("%-8s:\t", placecounts[i].place); //打印出生源地名字
for(m=0;m<placecounts[i].count;m++)
printf("%d ", placecounts[i].count);
printf("\n");
}
}
printf("\n");
}
struct PlaceCount placecounts[Totalcounts];这里数组大小不能用变量Totalcounts,你需要直接指定一个大小,比如10000
(1)你写文件的时候用的fprintf_s,结构体元素之间用逗号分隔了,但是后面所有的读文件都是用的fread,这么读出来的数据都是错误的。
用fprintf_s写文件,那么就用fscanf_s读文件。
(2)再showfromplace函数中,新定义的结构体使用了动态数组,这个在一些编译器中是不支持的。
(3)如果你使用的是vs2015以后的版本,fflush(stdin)已失效。在in函数中,是否继续输入的处理有问题。
代码修改如下:
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<dos.h>
#include<string.h>
#include<Windows.h>
#include<stdarg.h>
struct Student {
char name[10];//定义学生名字
char sno[13];//定义学生学号
char gender[10];//定义学生性别
char fromPlace[9];//定义学生生源地
char phone[12];//定义学生电话号码
};
struct Student stu;
struct Student studinfos[150];
int TotalCount = 0;
void in();//定义输入函数
void show();//定义查找函数
void showgender();//定义查看性别函数
void showfromplace();//定义查看生源地函数
int main(int argc, char* argv[]) {
int n;
//主菜单
while (1) {
printf_s("\t************************\n");
printf_s("\t* 学生信息管理系统 *\n");
printf_s("\t* 主菜单 *\n");
printf_s("\t* 1 输入学生信息 *\n");
printf_s("\t* 2 查找学生信息 *\n");
printf_s("\t* 3 学生性别占比 *\n");
printf_s("\t* 4 统计学生信息 *\n");
printf_s("\t* 0 退出系统 *\n");
printf_s("\t************************\n");
printf_s("\n");
printf_s("请输入选择的功能(4-0):\n");
scanf_s("%d", &n);
switch (n) {
case 0: {
printf_s("感谢您的使用,再见!\n");
return 0;
break;
}
case 1: {
in();
break;
}
case 2: {
show();
break;
}
case 3: {
showgender();
break;
}
case 4: {
showfromplace();
break;
}
}
}
printf("请输入选择的功能:\n");
return 0;
}
//const char* g_filename = "C:\\Users\\ALIENWARE\\Desktop\\student.txt";
const char* g_filename = "student_csdn.txt";
//输入函数
void in()
{
FILE* fp;
char yn = 'y';
if ((fp = fopen(g_filename, "a+")) != NULL)//以a模式打开文件
{
rewind(stdin);
while (yn == 'y')
{
printf_s("请输入学生信息\n");
printf_s("请输入姓名\n");
scanf_s("%s", stu.name, 8);
stu.name[8] = '\0';
printf_s("请输入学号\n");
scanf_s("%s", stu.sno, 12);
stu.sno[12] = '\0';
printf_s("请输入性别\n");
scanf_s("%s", stu.gender, 9);
stu.gender[9] = '\0';
printf_s("请输入生源地\n");
scanf_s("%s", stu.fromPlace, 8);
stu.fromPlace[8] = '\0';
printf_s("请输入手机号码\n");
scanf_s("%s", stu.phone, 11);
stu.phone[11] = '\0';
printf_s("姓名:%-8s 学号:%-12s 性别:%-9s 生源地:%-8s 手机号:%-11s\n", stu.name, stu.sno, stu.gender, stu.fromPlace, stu.phone);
fprintf_s(fp, "%s %s %s %s %s\n", stu.name, stu.sno, stu.gender, stu.fromPlace, stu.phone);
fflush(fp);//把文件缓冲区的内容写入磁盘
//fflush(stdin);//清除键盘缓存内容
rewind(stdin); //清空输入缓存 vs2015之前的版本可以使用 fflush(stdin);
//int y = getchar();
printf_s("是否继续输入学生信息(y/n)\n");
yn = getchar();
getchar();
//scanf_s("%c", &yn, 1);
}
fclose(fp);
}
else {
printf_s("文件打开错误!");
}
}
//查找函数
void show()
{
FILE* fp;
int stupos = 0;
fp = fopen(g_filename, "r");
printf_s("%-8s %-12s %-9s %-8s %-11s\n", "姓名", "学号", "性别", "生源地", "手机号码");
if (!fp)
return;
//while (fread(&studinfos[stupos], sizeof(struct Student), 1, fp) != NULL)
while (!feof(fp))
{
int res = fscanf_s(fp, "%s %s %s %s %s", studinfos[stupos].name, 8, studinfos[stupos].sno, 12, studinfos[stupos].gender, 9, studinfos[stupos].fromPlace, 8, studinfos[stupos].phone, 11);
if (res && studinfos[stupos].name[0] != '\0')
{
//这些其实都没用
studinfos[stupos].name[8] = '\0';
studinfos[stupos].sno[12] = '\0';
studinfos[stupos].gender[9] = '\0';
studinfos[stupos].fromPlace[8] = '\0';
studinfos[stupos].phone[11] = '\0';
printf_s("%-8s %-12s %-9s %-8s %-11s\n", studinfos[stupos].name, studinfos[stupos].sno, studinfos[stupos].gender, studinfos[stupos].fromPlace, studinfos[stupos].phone);
stupos++; //这里需要递增
}
}
fclose(fp);
}
//查看性别函数
void showgender() {
int male = 0, female = 0, error = 0;
int stupos = 0;
int i;
FILE* fp = NULL;
if ((fp = fopen(g_filename, "r+")) == NULL) {
printf_s("文件不存在!");
}
while (!feof(fp))/*文本结束,返回非零值 */ {
//if (fread(&studinfos[stupos], sizeof(struct Student), 1, fp) == 1)
int res = fscanf_s(fp, "%s %s %s %s %s", studinfos[stupos].name, 8, studinfos[stupos].sno, 12, studinfos[stupos].gender, 9, studinfos[stupos].fromPlace, 8, studinfos[stupos].phone, 11);
if (res && studinfos[stupos].name[0] != '\0')
{
stupos++;
}
}
if (stupos == 0) {
printf_s("文件没有内容!\n");
fclose(fp);
return;
}
else {
printf_s("这个班的学生有%d名学生。\n", stupos);
fclose(fp);
}
for (i = 0; i < stupos; i++) {
studinfos[i].gender[10] = '\0';
if (strncmp(studinfos[i].gender, "m", 10) == 0) {
male++;
}
else if (strncmp(studinfos[i].gender, "f", 10) == 0) {
female++;
}
else {
error++;
}
}
printf_s("男生占比%4.2f\n\n", (male * 1.0 / stupos));
printf_s("女生占比%4.2f\n\n", (female * 1.0 / stupos));
}
//定义查看生源地函数
void showfromplace() {
FILE* fp;
int stupos = 0;
int Totalcounts;
fp = fopen(g_filename, "r");
if (!fp)
return;
//while (fread(&studinfos[stupos], sizeof(struct Student), 1, fp) != NULL)
while (!feof(fp))
{
int res = fscanf_s(fp, "%s %s %s %s %s", studinfos[stupos].name, 8, studinfos[stupos].sno, 12, studinfos[stupos].gender, 9, studinfos[stupos].fromPlace, 8, studinfos[stupos].phone, 11);
if (studinfos[stupos].name[0] != '\0')
{
studinfos[stupos].name[8] = '\0';
studinfos[stupos].sno[12] = '\0';
studinfos[stupos].gender[2] = '\0';
studinfos[stupos].fromPlace[8] = '\0';
studinfos[stupos].phone[11] = '\0';
printf("%-8s %-12s %-2s %-8s %-11s\n", studinfos[stupos].name, studinfos[stupos].sno, studinfos[stupos].gender, studinfos[stupos].fromPlace, studinfos[stupos].phone);
stupos++;//下标位置加1
}
}
fclose(fp); //关闭文件
Totalcounts = stupos;
struct PlaceCount
{
char place[9]; //生源地
int count; //该生源地的人数
};
struct PlaceCount placecounts[150];// [Totalcounts] ; //创建一个结构体数组,每个元素包含一个char类型的place和int类型的count
int i;
for (i = 0; i < Totalcounts; i++) { //初始化结构体数组
placecounts[i].place[0] = '0';
placecounts[i].count = 0;
}
for (i = 0; i < Totalcounts; i++) //将studinfos结构体数组中的每个fromPlace拷贝到placecounts结构体数组中
{
strcpy(placecounts[i].place, studinfos[i].fromPlace);
}
int outer, inner;
struct PlaceCount tmp;//定义一个结构体变量用来交换
for (outer = 0; outer < Totalcounts - 1; outer++) {
//采用冒泡排序的方法将结构体数组按palce的大小进行排序
for (inner = 0; inner < Totalcounts - outer - 1; inner++) {
if (strcmp(placecounts[inner].place, placecounts[inner + 1].place) > 0)
{
tmp = placecounts[inner]; //创建临时变量tmp,用于交换前后两个元素的位置
placecounts[inner] = placecounts[inner + 1];
placecounts[inner + 1] = tmp;
}
}
}
for (i = 0; i < Totalcounts; i++)
{
printf("%s\n", placecounts[i].place);
}
int marks = 0;
placecounts[0].count = 1;
for (i = 1; i < Totalcounts; i++) //统计相同生源地的个数
{
if (strcmp(placecounts[i].place, placecounts[marks].place) == 0)
{//将已经排序好的结构体数组中的place元素进行比较,用marks=0作为起点,
//让它与后面的每一个生源地进行比较看是否相同,相同则那一生源地数目加1,
//i递增,marks不变,不同则将i赋值给marks,作为新起点与后面的生源地进行比较
placecounts[marks].count++;
}
else {
marks = i;
placecounts[marks].count++;
}
}
int m;
for (i = 0; i < Totalcounts; i++)
{
if (placecounts[i].count > 0) //避免重复打印相同的生源地
{
printf("%-8s:\t", placecounts[i].place); //打印出生源地名字
//for (m = 0; m < placecounts[i].count; m++)
printf("%d ", placecounts[i].count);
printf("\n");
}
}
printf("\n");
}