|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <conio.h>
#define MAX 100 //满分成绩
#define MIN 0 //最小成绩
#define LMN sizeof(struct student)
//student结构的大小
struct student *creat(); //创建链表
void print(struct student *head); //打印链表
struct student *del( struct student *head, int num); //del函数用于删除节点,*head即链表的头指针,num是要删除的结点num。
struct student *insert( struct student *head, struct student *stu_2 );
//第一个参数需要被插入的链表。第二个参数待插入的结点的地址。
struct student
{
long num;
char name[20] ;
float score;
struct studen *next;
};
int n = 0; //全局变量,用来记录存放了多少节点。
struct student *head = NULL;
int main ()
{
struct student * stu, *p, stu_2;
long num;
char ch;
float s;
s = MAX;
printf("小写字母 z 键是删除数据,小写字母 x 键是插入数据!!\n输入其它键则退出程序!!!\n\n");
printf("满分成绩为 %.1f 分!!!\n\n\n", s );
stu = creat();
p = stu;
print(p);
#if(1)
printf("\n\n\n");
while(1)
{
ch = getch();
if(ch == 'z' )
{
printf("请输入需要删除的学号 : ");
scanf("%d", &num);
print( del(p, num));
}
else if ( ch == 'x' )
{
printf("请输入新添加的学号 : ");
scanf("%d", &stu_2.num);
printf("请输入新添加的名字 : ");
scanf("%s", stu_2.name);
printf("请输入新添加的成绩 : ");
scanf("%f", &stu_2.score);
printf("\n");
while(1)
{
if( stu_2.score > MAX || stu_2.score < 0 )
{
printf("输入的成绩有误,请重新输入成绩 : ");
scanf("%f", &stu_2.score);
}
else
{
break;
}
}
p = insert( stu, &stu_2);
print(p);
}
else
{
break;
}
}
#endif
return 0;
}
struct student * creat(void) //创建链表
{
struct student *p1, *p2;
p1 = p2 = ( struct student * ) malloc(LMN);
printf("请输入学号 : ");
scanf("%d", &p1->num);
printf("请输入名字 : ");
scanf("%s", p1->name);
printf("请输入成绩 : ");
scanf("%f", &p1->score);
printf("\n");
while(1)
{
if( p1->score > MAX || p1->score < 0 )
{
printf("输入的成绩有误!\n请输入正确的成绩 : ");
scanf("%f", &p1->score);
printf("\n");
}
else
{
break;
}
}
while(p1->num != 0 )
{
n++;
if( 1 == n )
{
head = p1;
}
else
{
p2->next = p1;
}
p2 = p1;
p1 = (struct student * ) malloc(LMN);
printf("请输入学号 : ");
scanf("%d", &p1->num);
printf("请输入名字 : ");
scanf("%s", p1->name);
printf("请输入成绩 : ");
scanf("%f", &p1->score);
printf("\n");
if ( p1->score > MAX || p1->score < 0 )
{
printf("输入的成绩有误!!请输入正确的成绩 : ");
scanf("%f", &p1->score);
}
}
p2->next = NULL;
return (head);
}
void print(struct student *head)
{
struct student *p;
printf("\t现在这 %d 记录是 : \n", n );
p = head;
if(head != NULL)
{
do
{
printf("\t学号 : %ld\t名字 : %s\t成绩 : %5.2f\n", p->num, p->name, p->score);
p = p->next;
}while(p != NULL);
}
}
#if(1)
struct student * del( struct student * head, int num )
{
struct student *p1, *p2;
if( head == NULL )
{
printf("这个列表为空!!\n");
return head;
}
p1 = head;
while ( p1->num != num && p1->next != NULL )
{
p2 = p1;
p1 = p1->next;
}
if ( num == p1->num)
{
if ( head == p1 )
{
head = p1->next;
}
else
{
p2->next = p1->next;
}
printf("\n成功删除 NO : %d !!\n", num);
n -= 1;
}
else
{
printf("没有找到匹配的数据 : %d !\n", num);
}
return head;
}
#endif
#if(1)
struct student *insert( struct student *head, struct student *stu_2)
{
struct student *p1, *p2, *p0;
p1 = head;
p0 = stu_2;
if( NULL == head )
{
head = p0;
p0->next = NULL;
}
else
{
while( ( p0->num > p1->num) && ( p1->next != NULL) )
{
p2 = p1;
p1 = p1->next;
}
if( p0->num <= p1->num)
{
if( p1 == head )
{
head = p0;
p0->next = p1;
}
else
{
p2->next = p0;
p0->next = p1;
}
}
else
{
p1->next = p0;
p0->next = NULL;
}
}
n += 1;
return head;
}
#endif
我在第二次输入x键实现第二次插入时发现上一次的插入的数据不会显示,但是节点数还是正确的。
大家可以运行下试着按两下x键 就会发现问题了。
帮我看看这要怎么修改了,现在脑子有点乱,。。。。
本帖最后由 超凡天赐 于 2017-5-14 10:48 编辑
先说说你犯的最主要的错误,那就是你需要再写一个getchar()来接受你最后输入所留下的\n,为什么?因为getchar()和scanf("%c",&n)一样,也可以接受\n。详情见c语言学习笔记--chapter0-getchar,scanf以及缓冲区的概念-fontconfig-ChinaUnix博客 http://blog.chinaunix.net/uid-20568790-id-1632289.html。如果没有前面的getchar(),你最后只能退出这个程序。因为ch的值实际上是\n。当然了你还有其他一些问题,比如出现了long型向int型赋值,还有就是你为什么要使用条件编译?等等 ,好了废话不多说, #include <stdio.h>
#include <stdlib.h>
#define MAX 100 //满分成绩
#define MIN 0 //最小成绩
#define LMN sizeof(struct student)
//student结构的大小
struct student *create(); //创建链表
void print(struct student *head); //打印链表
struct student *del( struct student *head, long num); //del函数用于删除节点,*head即链表的头指针,num是要删除的结点num。
struct student *insert( struct student *head, struct student *stu_2 );
//第一个参数需要被插入的链表。第二个参数待插入的结点的地址。
struct student
{
long num;
char name[20] ;
float score;
struct student *next;
};
int n = 0; //全局变量,用来记录存放了多少节点。
struct student *head = NULL;
int main ()
{
struct student * stu, *p, stu_2;
long num;
char ch;
float s;
s = MAX;
printf("小写字母 z 键是删除数据,小写字母 x 键是插入数据!!\n输入其它键则退出程序!!!\n\n");
printf("满分成绩为 %.1f 分!!!\n\n\n", s );
stu = create();
p = stu;
print(p);
printf("\n\n\n");
getchar();
while(1)
{
ch = getchar();
if(ch == 'z' )
{
printf("请输入需要删除的学号 : ");
scanf("%ld", &num);
print( del(p, num));
}
else if ( ch == 'x' )
{
printf("请输入新添加的学号 : ");
scanf("%ld", &stu_2.num);
printf("请输入新添加的名字 : ");
scanf("%s", stu_2.name);
printf("请输入新添加的成绩 : ");
scanf("%f", &stu_2.score);
printf("\n");
while(1)
{
if( stu_2.score > MAX || stu_2.score < 0 )
{
printf("输入的成绩有误,请重新输入成绩 : ");
scanf("%f", &stu_2.score);
}
else
{
break;
}
}
p = insert( stu, &stu_2);
print(p);
}
else
{
break;
}
}
return 0;
}
struct student *create(void) //创建链表
{
struct student *p1, *p2;
p1 = p2 = ( struct student * ) malloc(LMN);
printf("请输入学号 : ");
scanf("%ld", &p1->num);
printf("请输入名字 : ");
scanf("%s", p1->name);
printf("请输入成绩 : ");
scanf("%f", &p1->score);
printf("\n");
while(1)
{
if( p1->score > MAX || p1->score < 0 )
{
printf("输入的成绩有误!\n请输入正确的成绩 : ");
scanf("%f", &p1->score);
printf("\n");
}
else
{
break;
}
}
while(p1->num != 0 )
{
n++;
if( 1 == n )
{
head = p1;
}
else
{
p2->next = p1;
}
p2 = p1;
p1 = (struct student * ) malloc(LMN);
printf("请输入学号 : ");
scanf("%ld", &p1->num);
printf("请输入名字 : ");
scanf("%s", p1->name);
printf("请输入成绩 : ");
scanf("%f", &p1->score);
printf("\n");
if ( p1->score > MAX || p1->score < 0 )
{
printf("输入的成绩有误!!请输入正确的成绩 : ");
scanf("%f", &p1->score);
}
}
p2->next = NULL;
return (head);
}
void print(struct student *head)
{
struct student *p;
printf("\t现在这 %d 记录是 : \n", n );
p = head;
if(head != NULL)
{
do
{
printf("\t学号 : %ld\t名字 : %s\t成绩 : %5.2f\n", p->num, p->name, p->score);
p = p->next;
}while(p != NULL);
}
}
struct student *del( struct student * head,long num )
{
struct student *p1, *p2 = NULL;
if( head == NULL )
{
printf("这个列表为空!!\n");
return head;
}
p1 = head;
while ( p1->num != num && p1->next != NULL )
{
p2 = p1;
p1 = p1->next;
}
if ( num == p1->num)
{
if ( head == p1 )
{
head = p1->next;
}
else
{
p2->next = p1->next;
}
printf("\n成功删除 NO : %ld !!\n", num);
n -= 1;
}
else
{
printf("没有找到匹配的数据 : %ld !\n", num);
}
return head;
}
struct student *insert( struct student *head, struct student *stu_2)
{
struct student *p1, *p2 = NULL, *p0;
p1 = head;
p0 = stu_2;
if( NULL == head )
{
head = p0;
p0->next = NULL;
}
else
{
while( ( p0->num > p1->num) && ( p1->next != NULL) )
{
p2 = p1;
p1 = p1->next;
}
if( p0->num <= p1->num)
{
if( p1 == head )
{
head = p0;
p0->next = p1;
}
else
{
p2->next = p0;
p0->next = p1;
}
}
else
{
p1->next = p0;
p0->next = NULL;
}
}
n += 1;
return head;
}
我的测试结果为 : 小写字母 z 键是删除数据,小写字母 x 键是插入数据!!
输入其它键则退出程序!!!
满分成绩为 100.0 分!!!
请输入学号 : 1001
请输入名字 : zhutianci
请输入成绩 : 99
请输入学号 : 1002
请输入名字 : zhutian
请输入成绩 : 98
请输入学号 : 0
请输入名字 : 0
请输入成绩 : 0
现在这 2 记录是 :
学号 : 1001 名字 : zhutianci 成绩 : 99.00
学号 : 1002 名字 : zhutian 成绩 : 98.00
z
请输入需要删除的学号 : 1002
成功删除 NO : 1002 !!
现在这 1 记录是 :
学号 : 1001 名字 : zhutianci 成绩 : 99.00
Program ended with exit code: 0
|
|