插入第一次成功,但是插入第二次就报失败,不知道为什么
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
void menu (void);
void clear_input_queue();
typedef struct Link{
char *elem;
struct Link *next;
}link;
link * initLink();
link * insertElem(link * p,char *elem,int add);
void display(link *p);
int main()
{
menu();
return 0;
}
void menu()
{
// 初始化列表
link *p=initLink();
display(p);
while(1){
printf("select: a:展示全部链表, b:插入链表.\n");
char ch;
ch = getchar();
switch(ch)
{
case 'a':
printf("Then you choose show all.\n");
display(p);
break;
case 'b':
printf("Please enter which position you will add .\n");
int n;
while(scanf("%d",&n)!=1);
{
while((ch=getchar())!='\n')
putchar(ch);
}
char name[50];
gets(name);
p = insertElem(p, name, n);
display(p);
break;
case 'c':
goto loop;
break;
}
}
loop:
printf("Exit");
}
link * initLink(){
link * p=(link*)malloc(sizeof(link)); //创建一个头结点
link * temp=p; //声明一个指针指向头结点,用于遍历链表
char *subways[] = {"第一个元素", "中间元素", "最后元素"};
for (int i=0; i<3; i++) {
link *a=(link*)malloc(sizeof(link));
a->elem=subways[i];
a->next=NULL;
temp->next=a;
temp=temp->next;
}
return p;
}
link * insertElem(link * p,char *elem,int add){
link * temp = p;//创建临时结点temp
link * c = NULL;
int i = 0;
//首先找到要插入位置的上一个结点
for (i = 1; i < add; i++) {
if (temp == NULL) {
printf("插入位置无效\n");
return p;
}
temp = temp->next;
}
c=(link*)malloc(sizeof(link));
strcpy(c->elem,elem);
// c->elem = tmp;
c->next = temp->next;
temp->next = c;
return p;
}
void display(link *p){
link* temp=p; //将temp指针重新指向头结点
//只要temp指针指向的结点的next不是Null,就执行输出语句。
while (temp->next) {
temp=temp->next;
char *data = temp->elem;
for (int i=0; i < strlen(data); i++){
printf("%c",data[i]);
}
if (temp->next)
printf(" --- ");
}
printf("\n");
}
第一个元素 --- 中间元素 --- 最后元素
select: a:展示全部链表, b:插入链表.
a
Then you choose show all.
第一个元素 --- 中间元素 --- 最后元素
select: a:展示全部链表, b:插入链表. // 这里为啥显示两遍??
select: a:展示全部链表, b:插入链表.
b
Please enter which position you will add .
2 // 插入位置
元素1 // 插入元素
第一个元素 --- 元素1 --- 中间元素 --- 最后元素
select: a:展示全部链表, b:插入链表.
b
Please enter which position you will add .
2
元素2 // 后面就没了,退出程序了
正常插入
修改如下,修改处见注释,供参考:
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
void menu(void);
void clear_input_queue();
typedef struct Link {
char* elem;
struct Link* next;
}link;
link* initLink();
link* insertElem(link* p, char* elem, int add);
void display(link* p);
int main()
{
menu();
return 0;
}
void menu()
{
// 初始化列表
link* p = initLink();
display(p);
while (1) {
printf("select: a:展示全部链表, b:插入链表.\n");
char ch;
ch = getchar();
switch (ch)
{
case 'a':
printf("Then you choose show all.\n");
getchar(); //修改
display(p);
break;
case 'b':
printf("Please enter which position you will add .\n");
int n;
while (scanf("%d", &n) != 1) //; 修改 多了';' 分号
{
while ((ch = getchar()) != '\n')
putchar(ch);
}
getchar(); //修改
char name[50];
gets(name);
p = insertElem(p, name, n);
display(p);
break;
case 'c':
goto loop;
break;
}
}
loop:
printf("Exit");
}
link* initLink() {
link* p = (link*)malloc(sizeof(link)); //创建一个头结点
link* temp = p; //声明一个指针指向头结点,用于遍历链表
char* subways[] = { "第一个元素", "中间元素", "最后元素" };
for (int i = 0; i < 3; i++) {
link* a = (link*)malloc(sizeof(link));
a->elem = subways[i];
a->next = NULL;
temp->next = a;
temp = temp->next;
}
return p;
}
link* insertElem(link* p, char* elem, int add) {
link* temp = p;//创建临时结点temp
link* c = NULL;
int i = 0;
//首先找到要插入位置的上一个结点
for (i = 1; i < add; i++) {
if (temp->next == NULL) { // if (temp == NULL) 修改
printf("插入位置无效\n");
return p;
}
temp = temp->next;
}
c = (link*)malloc(sizeof(link));
c->elem = (char*)malloc(sizeof(char) * 50); // 修改
strcpy(c->elem, elem);
// c->elem = tmp;
c->next = temp->next;
temp->next = c;
return p;
}
void display(link* p) {
link* temp = p; //将temp指针重新指向头结点
//只要temp指针指向的结点的next不是Null,就执行输出语句。
while (temp->next) {
temp = temp->next;
char* data = temp->elem;
for (int i = 0; i < strlen(data); i++) {
printf("%c", data[i]);
}
if (temp->next)
printf(" --- ");
}
printf("\n");
}
select: a:展示全部链表, b:插入链表. // 这里为啥显示两遍??
因为输入a之后还有一个回车,在getchar()后在调用一次
退出程序是因为程序第96行, strcpy(c->elem,elem); 这里c->elem指针没有申请内存
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
void menu(void);
void clear_input_queue();
typedef struct Link {
char* elem;
struct Link* next;
}link;
link* initLink();
link* insertElem(link* p, char* elem, int add);
void display(link* p);
int main()
{
menu();
return 0;
}
void menu()
{
// 初始化列表
link* p = initLink();
display(p);
while (1) {
printf("select: a:展示全部链表, b:插入链表.\n");
char ch;
scanf("%c",&ch);
switch (ch)
{
case 'a':
printf("Then you choose show all.\n");
display(p);
break;
case 'b':
printf("Please enter which position you will add .\n");
int n;
while (scanf_s("%d", &n) != 1);
{
while ((ch = getchar()) != '\n')
putchar(ch);
}
char name[50];
scanf_s("%s", &name);
p = insertElem(p, name, n);
display(p);
break;
case 'c':
goto loop;
break;
default:
break;
}
}
loop:
printf("Exit");
}
link* initLink() {
link* p = (link*)malloc(sizeof(link)); //创建一个头结点
link* temp = p; //声明一个指针指向头结点,用于遍历链表
char subways[][11] = { "第一个元素", "中间元素", "最后元素" };
for (int i = 0; i < 3; i++) {
link* a = (link*)malloc(sizeof(link));
a->elem = subways[i];
a->next = NULL;
temp->next = a;
temp = temp->next;
}
return p;
}
link* insertElem(link* p, char* elem, int add) {
link* temp = p;//创建临时结点temp
link* c = NULL;
int i = 0;
//首先找到要插入位置的上一个结点
for (i = 1; i < add; i++) {
if (temp == NULL) {
printf("插入位置无效\n");
return p;
}
temp = temp->next;
}
c = (link*)malloc(sizeof(link));
c->elem = (char*)malloc(sizeof(char));
c->next = NULL;
strcpy(c->elem, elem);
// c->elem = tmp;
c->next = temp->next;
temp->next = c;
return p;
}
void display(link* p) {
link* temp = p; //将temp指针重新指向头结点
//只要temp指针指向的结点的next不是Null,就执行输出语句。
while (temp->next) {
temp = temp->next;
char* data = temp->elem;
for (int i = 0; i < strlen(data); i++) {
printf("%c", data[i]);
}
if (temp->next)
printf(" --- ");
}
printf("\n");
}