C 学生管理系统_读取文件中得学生信息

1、

#define _CRT_SECURE_NO_WARNINGS
#define _CRT_NONSTDC_NO_DEPRECATE
#include<stdio.h>
#include<stdlib.h>
#include <string.h>

//学生节点。
typedef struct _STU
{
    char arrStuNum[10];
    char arrStuName[10];
    int iStuScore;
    struct _STU* pNext;//指向下一个节点。
}STUNODE;
//申明链表的头和尾。
STUNODE* g_pHead = NULL;
STUNODE* g_pEnd = NULL;
//添加一个尾部学生信息。
void AddStuMSG(char* arrStuNum[10], char arrStuName[10], int iStuScore);

//链表头部添加学生信息。
void AddStuMSGToLinkHead(char* arrStuNum[10], char arrStuName[10], int iStuScore);

//查找指定位置学生信息。
STUNODE* FindStuByNum(char *arrStuNum);

//指定位置添加学生信息。
void InSertNod(STUNODE *pTemp, char* arrStuNum[10], char arrStuName[10], int iStuScore);


//清空链表。
void FreeLinkData();

//打印数据(链表)。
void ShowStuData();

//显示指令。
void ShowOrder();

//删除指定的学生。
void DeleteStuNode(STUNODE*pNode);

//保存信息进入文件。
void SaveStuToFile();

//读取学生信息表。
void ReadStuFromFile();

int main()
{
    int nOrder=-1;

    char arrStuNum[10] = {'\0'};
    char arrStuName[10] = {'\0'};
    int iStuScore=-1;
    int  nFlag = 1;

    STUNODE* pTemp = NULL;


    //显示指令。
    ShowOrder();

    //读取学生信息表。
   ReadStuFromFile();

    
    while (nFlag)
    {
        printf("请输入操作指令(0为查看指令)\n");
        scanf("%d", &nOrder);
        switch (nOrder)
        {
        case 1://添加一个学生信息。
            printf("输入学号:");
            scanf("%s", arrStuNum);
            printf("输入姓名:");
            scanf("%s", arrStuName);
            printf("输入分数:");
            scanf("%d", &iStuScore);//取地址。
            AddStuMSG(arrStuNum,  arrStuName, iStuScore);
            break;
        case 10://头添加。
            printf("输入学号:");
            scanf("%s", arrStuNum);
            printf("输入姓名:");
            scanf("%s", arrStuName);
            printf("输入分数:");
            scanf("%d", &iStuScore);//取地址。
            AddStuMSGToLinkHead(arrStuNum, arrStuName, iStuScore);
            break;
        case 11://指定位置添加。

            printf("输入需要查找的学号:");
            scanf("%s", arrStuNum);
            pTemp = FindStuByNum(arrStuNum);
            if(NULL!=pTemp);
            {
                //插入。
                printf("输入学号:");
                scanf("%s", arrStuNum);
                printf("输入姓名:");
                scanf("%s", arrStuName);
                printf("输入分数:");
                scanf("%d", &iStuScore);
                InSertNod(pTemp, arrStuNum, arrStuName, iStuScore);

            }
            break;
        case 2://打印指定学生信息。
            printf("输入学号:");
            scanf("%s", arrStuNum);
            //查找。
            pTemp = FindStuByNum(arrStuNum);
            //打印。
            if (NULL != pTemp);
            {
                printf("学号:%s,姓名:%s,成绩:%d\n", pTemp->arrStuNum, pTemp->arrStuName, pTemp->iStuScore);

            }
            break;
        case 3:
            printf("输入需要修改的学号:");
            scanf("%s", arrStuNum);
            //查找。
            pTemp = FindStuByNum(arrStuNum);
            //打印。
            if (NULL != pTemp);
            {
             //修改学号。
                printf("输入修改后的学号:");
                scanf("%s", arrStuNum);
                strcpy(pTemp->arrStuNum ,arrStuNum);
                //修改姓名
                printf("输入修改后姓名:");
                scanf("%s", arrStuName);
                strcpy(pTemp->arrStuName ,arrStuName);
                //修改分数。
                printf("输入修改后分数:");
                scanf("%d", &iStuScore);
            }

            break;
        case 4:
            SaveStuToFile(); 
            //保存学生信息。
            break;
        /*case 5:
            ReadStuFromFile();*/
            break;
        case 6://删除指定学生节点。
            printf("输入需要删除的学号:");
            scanf("%s", arrStuNum);
            //查找。
            pTemp = FindStuByNum(arrStuNum);
            //打印。
            if (NULL != pTemp)
            {
                //调用删除学生的函数。
                DeleteStuNode(pTemp);

            }
            break;
        case 7:
            //释放链表。
            FreeLinkData();
            g_pHead = NULL;
            g_pEnd = NULL;
            //恢复。

            ReadStuFromFile();
            break;
        case 8://打印数据(链表)。
            ShowStuData();
        break;
        case 9:
            nFlag = 0;
            break;
        case 0:
            //查看指令。
            ShowOrder();
            break;
        default:
            printf("输入的指令不对");
            break;
        }
    }
    //保存。
    SaveStuToFile();
    //释放链表。
     FreeLinkData();
    system("pause");
    return 0;
}
//添加一个学生信息。
void AddStuMSG(char *arrStuNum[10], char arrStuName[10], int iStuScore)
{
    //逻辑
    //创建一个节点。
    STUNODE* pTemp = malloc(sizeof(STUNODE));

    //第一步,检验参数合法性。
    if (NULL==arrStuNum||NULL==arrStuName||iStuScore<0)
    {
        printf("学生信息输入错误。\n");
        return;
    }
    

    //节点成员赋初始值。
    strcpy(pTemp->arrStuNum, arrStuNum);//因为数组做参数传入时则完全是一个指针。
    strcpy(pTemp->arrStuName, arrStuName);//因为数组做参数传入时则完全是一个指针。
    pTemp->iStuScore = iStuScore;
    pTemp->pNext = NULL;

    //接在链表上。
    if (NULL == g_pHead || NULL == g_pEnd)
    {
        g_pHead = pTemp;
        g_pEnd = pTemp;
    }
    else
    {
        g_pEnd->pNext = pTemp;//链接。
        g_pEnd = pTemp;//向后移动。
    }
}

//清空链表。
void FreeLinkData()
{   //记录节点。
    STUNODE* pTemp = g_pHead;
    while (g_pHead!=NULL)
    {//记录节点。
        pTemp = g_pHead;
        //向后移动一个。
        g_pHead = g_pHead->pNext;
        //删除节点。
        free(pTemp);

    }
}
//打印数据。
void ShowStuData()
{
    STUNODE* pTemp = g_pHead;
    while (pTemp != NULL)
    {
        printf("学号:%s,姓名:%s,成绩:%d\n", pTemp->arrStuNum, pTemp->arrStuName, pTemp->iStuScore);
        //向下走一步。
        pTemp = pTemp->pNext;

    }
}

//显示指令。
void ShowOrder()
{
    printf("*******************学生管理系统******************\n");
    printf("******************系统操作指令如下****************\n");
    printf("***1、增加一个学生信息(尾添加)***\n");
    printf("***2、查找指定学生信息(姓名/学号)***\n");
    printf("***3、修改指定学生的信息***\n");
    printf("***4、保存信息的信息到文件***\n");
    //printf("***5、读取文件中的业主信息***\n");
    printf("***6、删除指定学生的信息***\n");
    printf("***7、恢复删除的学生信息***\n");
    printf("***8、显示所有学生信息***\n");
    printf("***9、退出系统***\n");
    printf("***10、增加一个学生信息(头添加)***\n");
    printf("***11、增加一个学生信息(指定位置添加)***\n");
    printf("***0、查看指令***\n");
    printf("*****************************************************\n");

}

//链表头部添加信息。
void AddStuMSGToLinkHead(char arrStuNum[10], char arrStuName[10], int iStuScore)
{
    //检测参数的合法性。
    if (NULL==arrStuNum||NULL==arrStuName||iStuScore<0)
    {
        printf("学生信息输入错误。\n");
        return;
    }
    //创建一个节点。
    STUNODE *pTemp = malloc(sizeof(STUNODE));
    
    //成员赋值。

    strcpy(pTemp->arrStuNum, arrStuNum);//因为数组做参数传入时则完全是一个指针。
    strcpy(pTemp->arrStuName, arrStuName);//因为数组做参数传入时则完全是一个指针。
    pTemp->iStuScore = iStuScore;
    pTemp->pNext = NULL;
    
    if (NULL==g_pHead||NULL==g_pEnd)
    {
        //链表为空。
        g_pHead = pTemp;
        g_pEnd = pTemp;
    }
    else
    {
        //新节点的下一个指向头。
        pTemp->pNext = g_pHead;
        //向前移动一个。
        g_pHead = pTemp;
    }
}

//查找指定位置学生信息。
STUNODE* FindStuByNum(char* arrStuNum)
{
    STUNODE* pTemp = g_pHead;
    //检测参数的合法性。
    if (NULL == arrStuNum)
    {
        printf("学号输入错误!\n");
        return NULL;
    }
   //判断链表是否为空。
    if (NULL==g_pHead||NULL==g_pEnd)
    {
        printf("链表为NULL!\n");
        return NULL;
    }
    //遍历链表。
    while (pTemp!=NULL)
    {
        if (0==strcmp(pTemp->arrStuNum,arrStuNum))
        {
            return pTemp;
        }
        pTemp = pTemp->pNext;
    }
    printf("查无此节点!\n");
    return NULL;
}


//指定位置添加学生信息。
void InSertNod(STUNODE* pTemp, char* arrStuNum[10], char arrStuName[10], int iStuScore)
{
    //创建节点。
    STUNODE* pNewTemp = malloc(sizeof(STUNODE));
    //成员赋值。
    strcpy(pNewTemp->arrStuNum, arrStuNum);//因为数组做参数传入时则完全是一个指针。
    strcpy(pNewTemp->arrStuName, arrStuName);//因为数组做参数传入时则完全是一个指针。
    pNewTemp->iStuScore = iStuScore;
    pNewTemp->pNext = NULL;

    if (pTemp==g_pEnd)//是尾节点。
    {
        g_pEnd->pNext = pNewTemp;//尾结点下一个指向pNewTmep。
        g_pEnd = pNewTemp;//尾结点变成pNewTmep。
    }
    else
    {
        pNewTemp->pNext = pTemp->pNext;
        pTemp->pNext = pNewTemp;
        
    }
}

//删除指定的学生。
void DeleteStuNode(STUNODE* pNode)
{//只有一个节点。
    if (g_pHead==g_pEnd)
    {
        free(g_pHead);
        g_pHead = NULL;
        g_pEnd = NULL;
        printf("删除成功\n");

    }
    else if(g_pHead->pNext == g_pEnd)//有两个节点。
    {
        if (g_pHead==pNode)
        {
            g_pHead = g_pEnd;
            printf("删除成功\n");

        }
        else
        {
            free(g_pEnd);
            g_pEnd = g_pHead;
            g_pHead->pNext = NULL;//g_pEnd虽然被删除,但空间仍然被g_pHead->pNext指向。易导致操作越界。
            printf("删除成功\n");

        }
    }
    else//常规删除。
    {
        STUNODE* pTemp = g_pHead;
        //判断头。
        if (g_pHead==pNode)
        {
         //记住头。
            pTemp = g_pHead;
            g_pHead = g_pHead->pNext;
            free(pTemp);
            pTemp = NULL;
            return;
        }
        while (pTemp)
        {
            if (pTemp->pNext==pNode)
            {
                //删除。
                if (pNode == g_pEnd)
                {
                    free(pNode);
                    pNode = NULL;
                    g_pEnd = pTemp;
                    g_pEnd->pNext = NULL;
                    return;
                }
                else
                {
                    //记住要删除的节点。
                    STUNODE* p = pTemp->pNext;
                    //链接
                    pTemp->pNext = pTemp->pNext->pNext;
                    //释放节点。
                    free(p);
                    p = NULL;
                    return;
                }
            }
            pTemp = pTemp->pNext;
        }
    }
    
}

//保存信息进入文件。
void SaveStuToFile()
{//判断链表是否为空。
    FILE* pFile = NULL;
    STUNODE* pTemp = g_pHead;
    char strBuf[30] = { 0 };
    char strScore[10] = { 0 };
    if (NULL==g_pHead)
    {
        printf("链表为空,没有学生信息\n");
        return;
    }
    //打开文件。
    pFile = fopen("dad.txt","wb+");
    if (NULL==pFile)
    {
        printf("没有学生\n");
        return;
    }
    //操作文件指针。
    while (pTemp)
    {//学号复制进去。
        strcpy(strBuf, pTemp->arrStuNum);
        strcat(strBuf, ",");
        //姓名复制进去。
        strcat(strBuf, pTemp->arrStuName);
        strcat(strBuf, ",");
        //分数复制。
        itoa(pTemp->iStuScore,strScore,10);//先将整型转换为字符串。
        strcat(strBuf, strScore);

        fwrite(strBuf, 1, strlen(strBuf), pFile);//每次写入1*strLen(strBuf)个字节。
        fwrite("\r\n", 1, strlen("\r\n"), pFile);

        pTemp = pTemp->pNext;
    }
    //关闭文件。
    fclose(pFile);

}

//读取学生信息表。
void ReadStuFromFile()
{
    FILE* pFile = fopen("dad.txt", "rb+");
    char strBuf[30] = { 0 };
    char strStuNum[10] = {0};
    char strStuName[10] = { 0 };
    char strStuScore[10] = { 0 };
    int nCount = 0;
    int j = 0;
    if (NULL==pFile)
    {
        printf("文件打开失败\n");
        return;
    }

    //1、操作指针,读取函数。
    while (NULL!= fgets(strBuf, 30, pFile))// 一次读一行。
    {
        
        int i = 0;
        nCount = 0;
         j = 0;
        //fgets(strBuf, 30, pFile);
        for ( i = 0; strBuf[i]!='\r'; i++)
        {
            if (0==nCount)//没到","
            {
                strStuNum[i] = strBuf[i];
                if (',' == strBuf[i])
                {
                    strStuNum[i] = '\0';
                    nCount++;
                }
            }
            else if (1==nCount)//到第一个","。
            {
                
                strStuName[j] = strBuf[i];
                j++;
                if (',' == strBuf[i])
                {
                    strStuName[j] = '\0';
                    nCount++;
                    j = 0;
                }
                
            }
            else//第二个","。
            {
                strStuScore[j] = strBuf[i];
                j++;
            }

            
        }
        //2、插入链表。
        AddStuMSG( strStuNum,strStuName, atoi(strStuScore));//字符串转为整数。
    }
        fclose(pFile);
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

clown_30

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值