各位看看这些问题怎么解决,还有在输出第二个和第三个的时候有问题

img

img


#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");
}