A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

30黑马币
编写一个学生管理系统程序,用来记录学生的信息(包括姓名、年龄、性别、学号、分数),提供增加、删除、查询学生信息的入口。(C语言)
//链表编写一个学生管理系统程序遇到问题,请大神解决。main函数好像不对,然后只能添加1个学生信息,怎么解决?或者大神改进代码,谢谢。

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

//创建节点结构,记录学生的信息
struct student{
    char name[20]; //姓名
    int age;       //年龄
    char sex;        //性别
    int no;    //学号
    int score;     //分数
    struct student*next;    //指向下一个节点的指针
};


int count;      //链表长度,作用是表示链表中节点数量
//create函数创建列表,该函数将会返回链表头指针
struct student *create()
{
    struct student *head=NULL;    //初始化链表,头指针为空
    struct student *end,*new;     //end指向原来尾节点,new指向新创建节点
    int count=0;           //初始化链表长度
    end=new=(struct student*)malloc(sizeof(struct student));
    /*使用malloc函数分配内存,end与new都指向第一个分配的内存。malloc函数原型: void*malloc(unsigned int size);功能:是在内存中动态地分配一块size大小的内存空间,返回一个指针,该指针指向分配的内存空间,如果出现错误则返回NULL;
     类似函数:calloc函数,其原型:void*calloc(unsigned n,unsigned size),功能:在内存中动态分配n个长度size的连续空间数组,会返回一个指针,该指针指向动态分配的连续内存空间地址, 如果出现错误则返回NULL; */
    printf("请输入学生信息(包括姓名、年龄、性别、学号、分数):\n");
    scanf("%s",new->name);  //姓名
    scanf("%d",&new->age);  //年龄
    scanf("%c",&new->sex);   //性别
    scanf("%d",&new->no);   //学号
    scanf("%d",&new->score);   //分数
    while(new->no!=0){
        count++;                 //表示链表节点增加
        //判断新加入节点是否第一次加入节点
        if(count==1)
        { //第一次加入节点时,新节点为首节点也为最后一个节点
            new->next=head;   //先将新节点指向为空
            end=new;      //跟踪新加入的节点
            head=new;     //头指针指向首节点
        }
        else
        {//加入新节点时链表中已有节点
            new->next=NULL;      //新节点的指针为空
            end->next=new;        //原来尾节点指向新节点
            end=new;              //end指向新节点
        }
        new=(struct student*)malloc(sizeof(struct student));
        /*再次分配节点内存空间,然后再次向其中输入数据,通过while循环再次判断输入的数据是否符合节点的要求。当要求不适合时,执行下面的代码,调用free函数将不符合要求的节点空间进行释放*/
        scanf("%s",new->name);
        scanf("%d",&new->age);
        scanf("%c",&new->sex);
        scanf("%d",&new->no);
        scanf("%d",&new->score);
    }
    free(new);  //释放没有用到的空间
    /*free函数原型:void free(void*ptr);  功能:使用由指针ptr指向的内存区,使部分内存区能被其他变量使用。ptr是最近一次调用calloc或malloc函数返回的值。free函数无返回值。*/
    return head;
}
//以上通过动态分配内存空间的方式创建完成链表


void print(struct student*head)     //输出链表,查询信息
{
    struct student*temp;             //循环使用临时指针
    int n=1;                   //表示链表中节点的序号
    printf("学生管理系统共有%d人\n",count);
    printf("\n");
    temp=head;     //指针得到首节点的地址
    while(temp!=NULL)
    {
        printf("学号%d的学生信息如下:\n",n);   //输出学号
        printf("姓名:%s\n",temp->name);        //输出姓名
        printf("年龄:%d\n",temp->age);         //输出年龄
        printf("性别:%c\n",temp->sex);        //输出性别
        printf("分数:%d\n",temp->score);          //输出分数
        printf("\n");
        temp=temp->next;                        //移动临时节点到下一个节点
        n++;
    }
}
/*print函数将链表数据输出,其参数head表示链表头节点。函数中定义一个临时指针temp用来循环操作,定义整型变量i表示链表节点序号,然后将临时指针temp保存首节点地址。
while语句将所有节点中保存的数据都显示输出,其中每输出一个节点内容后,就移动temp指针指向下一个节点地址,当为最后一个节点时,所拥有的指针指向NULL,循环结束*/


//在链表头节点位置插入节点[有三种插入操作(链表头节点位置插入节点,某个节点位置进行,像创建结构时在链表后面添加节点),思路一样]
//向链表中添加节点
struct student *insert(struct student*head)
{
    struct student*new;       //指向新分配空间
    printf("增加学生信息(包括姓名、年龄、性别、学号、分数):\n");
    new=(struct student*)malloc(sizeof(struct student));    //分配内存空间,并返回指向该内存空间的指针
    scanf("%s",new->name);
    scanf("%d",&new->age);
    scanf("%c",&new->sex);
    scanf("%d",&new->no);
    scanf("%d",&new->score);
    new->next=head;   //新节点指针指向原来首节点
    head=new;      //头指针指向新节点
    count++;        //增加链表节点数量
    return head;     //返回头指针
}
/*链表的插入需要为插入的链表分配内存,然后向新节点输入数据,这样一个新节点就创建完成了。如果需要将这个节点插入链表中,首先需要将新节点的指针指向原来的首节点,保存首节点的地址,然后将头指针指向新节点,这样就完成节点的连接操作,最后增加链表的节点数量*/


//删除链表节点
void delete(struct student*head,int n)       //head表示头节点,n表示要删除节点序号或下标
{
    int i;                          //控制循环次数
    struct student*temp;             //临时指针
    struct student*p;              //表示要删除节点前的节点
    temp=head;                   //得到头节点
    p=temp;
    printf("删除学号为%d的学生\n",n);
    for(i=1;i<n;i++)           //for循环使temp指向要删除的节点
    {
        p=temp;
        temp=temp->next;
    }
    p->next=temp->next;        //连接删除节点两边节点
    free(temp);                  //释放要删除节点的内存空间
    count--;                    //减少链表中节点的元素个数
}
/*delete函数传递两个参数,head表示链表头指针,n表示要删除的节点在链表中位置。定义变量i用来控制循环次数,然后定义两个指针,分别表示要删除的节点和这个节点之前的节点。输出一行提示信息表示要进行删除操作,之后利用for语句进行循环操作找到要删除的节点,连接删除节点两边的节点,并使用free函数将temp指向的内存空间进行释放。之后在main函数中添加代码执行删除操作,将链表中第二个节点进行删除*/

     int main(){
     struct student*head;        //定义头节点
     head=creaead);                //创建节点
     head=insert(head);           //增加学生信息
     delete(head,1);              //删除学生信息,例如删除第二个节点操作
     print(head);                 //输出链表
     return 0;
     }

最佳答案

查看完整内容

#include int menu(); void init(); void listStu(); int insertNewStu(int row); int deleteByNo(); void analyse(); int queryByNo(); int modifyInfoByNo(); int getStuRowByNo(char no[]); char students[50][300] ; int stu_num = 2; void main() { int opt; int result=1; init(); while(result) { if(result==0) { break; } opt = menu(); switch(opt){ case 1: //printf("\t执行操作:输入 ...

7 个回复

倒序浏览
#include <stdio.h>

int menu();
void init();
void listStu();
int insertNewStu(int row);
int deleteByNo();
void analyse();
int queryByNo();
int modifyInfoByNo();
int getStuRowByNo(char no[]);

char students[50][300] ;
int stu_num = 2;

void main()
{
        int opt;
        int result=1;
        init();

        while(result)
        {
               
                if(result==0)
                {
                        break;
                }
                opt = menu();
                switch(opt){
                case 1:
                        //printf("\t执行操作:输入学员资料\n");
                        result = insertNewStu(stu_num);       
                        stu_num=stu_num+1;
                        break;
                case 2:
                //        printf("\t执行操作:删除学员资料\n");
                        result=deleteByNo();
                        stu_num=stu_num-1;
                        break;
                case 3:
                        //printf("\t执行操作:查找学员资料\n");
                        result=queryByNo();
                        break;
                case 4:
                        //printf("\t执行操作:修改学员资料\n");
                        result=modifyInfoByNo();
                        break;
                case 5:
                        //printf("\t执行操作:输出学员信息数据\n");
                        listStu();
                        break;
                case 0:
                        printf("\n\t谢谢使用!\n");
                        result=0;
                        break;
                default:
                        printf("\t您的选择有误。\n");
                }
        }
}

int menu()
{
    int option;
        printf("\n\t--------------------------------------------------\n");
        printf("\t|\t\t学员信息管理系统\t\t|\n");
        printf("\t--------------------------------------------------\n\n");
        printf("\t1.输入学员资料\n");
        printf("\t2.删除学员资料\n");
        printf("\t3.查找学员资料\n");
        printf("\t4.修改学员资料\n");
        printf("\t5.输出学员信息数据\n");
        printf("\t0.退出\n\n");       
        printf("\t请选择您要进行的操作:");
        scanf("%d",&option);
        return option;
}

void init(){
        strcpy(students[0], "2010-$-张学友-$-男-$-香港-$-13601234567-$-98-$-89-$-");
        strcpy(students[1], "2011-$-王菲-$-女-$-北京-$-15887654321-$-99-$-100-$-");


}

void listStu()
{


        char temp[300]="";
        int i;

        printf("\n\t****现存的学员信息****\n");
        printf("学号\t");
        printf("姓名\t");
        printf("性别\t");
        printf("地址\t");
        printf("手机\t\t");
        printf("Java\t");
        printf(".Net\n");

        //针对每一行,进行解析
        for(i=0;i<stu_num;i++)
        {
                strcpy(temp,students[i]);
                //打印每一行的每个信息项
                while(strlen(temp)!=0)
                {               
                        analyse(temp);
                }
                printf("\n");
        }
}


void analyse(char c[])
{       
        int i,j;
        int token;
        char p_temp[100]="";

        //该行第一个分隔符前的信息项解析出来
        for(j=0;j<strcspn(c, "-$-");j++)
        {
                        p_temp[j]=c[j];
        }
        printf("%s\t",p_temp);
        //去掉已经解析出的项,即把每项信息向前前移动位置
        token=strcspn(c, "-$-");
        for(j=0;j<strlen(c)-token;j++)
        {
                c[j]=c[token+3+j];

        }
}

int insertNewStu(int row)
{
        int flag=0;//标识前项信息是否录入正确
        int i;
        char stu_temp[1][300];//用于存储该学员的信息
        int i_temp;
        char n_temp[30];
        char a_temp[10];
        char c_temp[10];


        //输入学号
        while(flag==0)
        {
                printf("\n\t请输入学员学号:");
                scanf("%d",&i_temp);
                if(i_temp<1000 ||i_temp>9999)
                {
                        printf("\t学号必须是4位数字!");
                        continue;
                }else
                {
                       
                        sprintf(c_temp,"%d",i_temp);
                        strcpy(stu_temp[0], c_temp);
                        strcat(stu_temp[0], "-$-");
                        flag=1;
                }
        }

        //输入姓名
        while(flag==1)
        {               
                printf("\n\t请输入学员姓名:");
                scanf("%s",&n_temp);
                if(strlen(n_temp) >= 20)
                {
                        printf("\t姓名长度过长!\n");               
                        continue;
                }else
                {
                        strcat(stu_temp[0], n_temp);
                        strcat(stu_temp[0], "-$-");
                        flag=2;
                }
        }

        //输入性别
        while(flag==2)
        {               
                printf("\n\t请输入性别(1.男 2.女):");
                scanf("%d",&i_temp);
                if(i_temp!=1 && i_temp!=2)
                {
                        printf("\t性别选择错误,请重新选择!\n");               
                        continue;
                }else
                {
                        if(i_temp==1)
                        {
                                strcat(stu_temp[0], "男");                       
                        }else
                        {
                                strcat(stu_temp[0], "女");                       
                        }
                        strcat(stu_temp[0], "-$-");
                        flag=3;               
                }
        }

        //输入地址
        while(flag==3)
        {               
                printf("\n\t请输入学员地址:");
                scanf("%s",&a_temp);
                if(strlen(a_temp) >30)
                {
                        printf("\t地址长度过长\n");               
                        continue;
                }else
                {
                        strcat(stu_temp[0], a_temp);
                        strcat(stu_temp[0], "-$-");
                        flag=4;
                }
        }

        //输入手机号
        while(flag==4)
        {
                printf("\n\t请输入手机号码:");
                scanf("%s",&c_temp);
                //判断手机号码合法性
                for(i = 0; i < strlen(c_temp); i++){
                        if(c_temp[i] < '0' || c_temp[i] > '9'){
                                printf("\t手机中包含非数字字符\n");                               
                                break;;
                        }
                }
                if(strlen(c_temp)!=11)
                {
                        printf("\t手机位数不正确!");                       
                        continue;
                       
                }else
                {
                        strcat(stu_temp[0], c_temp);
                        strcat(stu_temp[0], "-$-");
                        flag=5;
                }
        }

        //输入成绩
        while(flag==5)
        {
                printf("\n\t请输入Java成绩:");
                scanf("%d",&i_temp);
                if(i_temp<0 ||i_temp>100)
                {
                        printf("\t成绩非法!");
                        continue;
                }else
                {
                       
                        sprintf(c_temp,"%d",i_temp);
                        strcat(stu_temp[0], c_temp);
                        strcat(stu_temp[0], "-$-");
                        flag=6;
                }
        }
        while(flag==6)
        {
                printf("\n\t请输入.Net成绩:");
                scanf("%d",&i_temp);
                if(i_temp<0 ||i_temp>100)
                {
                        printf("\t成绩非法!");
                        continue;
                }else
                {                       
                        sprintf(c_temp,"%d",i_temp);
                        strcat(stu_temp[0], c_temp);
                        strcat(stu_temp[0], "-$-");
                        flag=7;
                }
        }

        //确认新信息增加是否正确
        printf("\n\t********确认学员信息如下********\n");
        printf("\t%s",stu_temp);
        printf("\n\n\t确认信息输入是否正确(Y/N):");
        scanf("%s",&c_temp);
        if(strcmp(c_temp,"y")==0 ||strcmp(c_temp,"Y")==0 )
        {
                strcpy(students[row],stu_temp[0]);        //写入students的第row行       

        }else
        {
                insertNewStu(row);
        }
        return flag;
}


int getStuRowByNo(char no[])
{
        int i,j;
        int pos=-1;
        char temp[5]="";
        //按行搜索
        for(i=0;i<stu_num;i++)
        {
                //搜索该行的列
                for(j=0;j<strcspn(students[i],"-$-");j++)
                {
                        temp[j]=students[i][j];
                }
                //如果找到,返回所在行i
                if(strcmp(no,temp) == 0)
                {
                        pos=i;
                        break;       
                }
        }
        return pos;
}

int deleteByNo()
{
        char no[5];
        int row;
        int i,j;

        printf("\n\t请输入要删除的学号:");
        scanf("%s",no);
        row=getStuRowByNo(no);//获取学员所在行

        if(row==-1)
        {
                printf("\t\n********没有该学号学员的信息,请核实学号********\n");
                return -1;
        }else
        {
                for(i=row;i<50;i++)
                {
                        for(j = 0; j < 300; j++)
                                students[i][j]=students[i+1][j];
                }               
                printf("\n\t********删除成功********\n");
                return 1;
        }
}

int queryByNo()
{
        char no[5];
        int row;
        char temp[300]="";

        printf("\n\t请输入要查找的学号:");
        scanf("%s",no);
        row=getStuRowByNo(no);//获取学员所在行

        if(row==-1)
        {
                printf("\t\n********没有该学号学员的信息,请核实学号********\n");
                return -1;
        }else
        {
                strcpy(temp,students[row]);
                printf("\n********查找到学员信息如下********\n");
                printf("学号\t");
                printf("姓名\t");
                printf("性别\t");
                printf("地址\t");
                printf("手机\t\t");
                printf("Java\t");
                printf(".Net\n");

                while(strlen(temp)!=0)
                {               
                        analyse(temp);
                }
                printf("\n");
                return 1;
        }
}

int modifyInfoByNo()
{
        char no[5];
        int row;
        char temp[300]="";

        printf("\n\t请输入要修改的学号:");
        scanf("%s",no);
        row=getStuRowByNo(no);//获取学员所在行

        if(row==-1)
        {
                printf("\t\n********没有该学号学员的信息,请核实学号********\n");
                return -1;
        }else
        {
                return insertNewStu(row);
                //return 1;
        }
}

点评

虽然不是链表做的,谁先回复就给谁了。  发表于 2015-4-24 19:33
回复 使用道具 举报
因代码受限,注释被我删除,你应该看得懂,请自行添加吧!功能完善:)
回复 使用道具 举报
dgrlucky 发表于 2015-4-24 17:18
因代码受限,注释被我删除,你应该看得懂,请自行添加吧!功能完善

既然没人解答,黑马币就给你了。
我的题目没改一个字就把代码提交了,得了9.5分
回复 使用道具 举报
dgrlucky 发表于 2015-4-24 17:18
因代码受限,注释被我删除,你应该看得懂,请自行添加吧!功能完善

不好意思,24小时评分超出限制,明天再评分吧。
回复 使用道具 举报

strcopy,strcat函数要加头文件#include<string.h>
void main()改为int  main()
while中输入姓名、输入地址、输入手机号代码中scanf("%s",&a_temp);把取地址符去掉scanf("%s",a_temp);
确认新信息增加是否正确代码中 printf("\t%s",stu_temp);改为 printf(“\t%s”,*stu_temp)

有个问题,增加学生信息输完后,问是否正确(y\no),我故意输no,编译器报错,死循环了:请输入学号   四位数
编译器崩溃了,我晕;其他的功能没看
回复 使用道具 举报
魔主 发表于 2015-4-24 19:36
不好意思,24小时评分超出限制,明天再评分吧。

好的!谢谢:P
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马