我一直在尝试这段代码。
我认为逻辑正常但是当调用display_rev函数时程序突然终止
这里是display_rev的代码
void display_rev(emp_node *head) {
emp_node *p=head, *q;
while(p->next != NULL)
p=p->next;
while(p!=head || p==head){
q=head;
display_rec(p);
while(q->next != p)
q=q->next;
p=q;
}
}
这是我的整个代码
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
//Declarations===============================================================
typedef struct //employee record
{
int emp_id;
char name[150];
char mob_no[11];
float salary;
int proj[5];
struct emp_node *next;
} emp_node;
emp_node* add_rec(emp_node*);
emp_node* create_db(emp_node*);
emp_node* search_db(emp_node*, int);
emp_node* delete_rec(emp_node*, int);
void read_name(emp_node*);
void read_mob(emp_node*);
void display_db(emp_node*);
void display_rec(emp_node*);
void display_rev(emp_node*);
void modify_rec(emp_node*);
void swtch(emp_node*);
//===========================================================================
int main() {
char ans;
emp_node *head = NULL;
head = create_db(head);
display_db(head);
do {
swtch(head);
printf("\n\n\tDo you want to continue (y/n) : ");
getchar();
scanf("%c", &ans);
} while (ans == 'y' || ans == 'Y');
return 0;
}
//Definitions================================================================
emp_node* create_db(emp_node *head) //database creation
{
int i = 1, no;
emp_node *p;
printf("Enter number of employees:");
scanf("%d", &no);
printf("\n\n");
head = (emp_node *) malloc(sizeof(emp_node));
head = add_rec(head);
head->next = NULL;
p = head;
while (i < no) {
p->next = (emp_node *) malloc(sizeof(emp_node));
p = p->next;
p = add_rec(p);
p->next = NULL;
i++;
}
return head;
}
emp_node* add_rec(emp_node *p) //new record
{
int j;
printf("\n\tEmployee ID : ");
scanf("%d", &(p->emp_id));
printf("\n\tFirst Name:");
read_name(p);
printf("\n\tMobile No.:");
read_mob(p);
printf("\n\tSalary :");
scanf("%f", &(p->salary));
printf(
"\n\tEnter \"1\" for the projects employee is working on, otherwise enter \"0\": \n");
for (j = 0; j < 5; j++) {
printf("\n\t\tProject No. %d : ", j + 1);
scanf("%d", &(p->proj[j]));
while (p->proj[j] != 1 && p->proj[j] != 0) {
printf("\n\nInvalid entry!! Please re-enter.");
printf("\n\t\tProject No. %d : ", j + 1);
scanf("%d", &(p->proj[j]));
}
}
printf("\n\n\n");
return p;
}
void read_name(emp_node *p) //validation for name
{
int j, len;
scanf("%s", p->name);
len = strlen(p->name);
for (j = 0; j < len; j++) {
if (!isalpha(p->name[j])) {
printf(
"\n\n\tInvalid name!!Can contain only characters. Please Re-enter.\n");
printf("\n\tName : ");
read_name(p);
}
}
}
void read_mob(emp_node *p) //validation for mobile no.
{
int j;
scanf("%s", p->mob_no);
while (strlen(p->mob_no) != 10) {
printf("\n\nInvalid Mobile No!!Please Re-enter");
printf("\n\n\tMobile No.:");
read_mob(p);
}
for (j = 0; j < 10; j++) {
if (!(48 <= p->mob_no[j] && p->mob_no[j] <= 57)) {
printf(
"\n\nInvalid Mobile No!!Can contain only digits. Please Re-enter.");
printf("\n\n\tMobile No.:");
read_mob(p);
}
}
}
void display_db(emp_node *head) //displaying whole database
{
emp_node *p;
p = head;
printf("\n\n\t\t****** EMPLOYEE DATABASE ******\n");
printf(
"\n==============================================================================");
printf("\n Id.\t Name\t\t Mobile No\t Salary\t Projects\n");
while (p != NULL) {
display_rec(p);
p = p->next;
printf("\n\n\n");
}
printf(
"\n==============================================================================");
}
void swtch(emp_node *head) //function for menu and switch case
{
int cho, x;
emp_node *p;
printf("\n\n\t\t****** MENU ******");
printf(
"\n\n\t1. insert Record\n\t2. Search Record\n\t3. Modify Record\n\t4. Delete Record\n\t5. Display Reverse\n\t6. Exit");
printf("\n\tWhich operation do you want to perform? ");
scanf("%d", &cho);
switch (cho) {
case 1:
p=head;
while(p->next != NULL)
p=p->next;
p->next = (emp_node *) malloc(sizeof(emp_node));
p=p->next;
p = add_rec(p);
p->next = NULL;
display_db(head);
break;
case 2:
printf("\n\n\tEnter employee ID whose record is to be Searched :");
scanf("%d", &x);
p = search_db(head, x);
if (p == NULL)
printf("\n\nRecord not found.");
else
display_rec(p);
break;
case 3:
printf("\n\n\tEnter employee ID whose record is to be modified :");
scanf("%d", &x);
p = search_db(head, x);
if (p == NULL)
printf("\n\nRecord not found.");
else
modify_rec(p);
display_db(head);
break;
case 4:
printf("\n\n\tEnter employee ID whose record is to be deleted :");
scanf("%d", &x);
head = delete_rec(head, x);
display_db(head);
break;
case 5:
display_rev(head);
case 6:
exit(0);
default:
printf("Invalid Choice!! Please try again.");
}
}
emp_node* search_db(emp_node *head, int id) //search database
{
emp_node *p = head;
while (p != NULL) {
if (p->emp_id == id)
return p;
p = p->next;
}
return NULL;
}
void display_rec(emp_node *p) //display a single record
{
int j;
printf("\n %d", p->emp_id);
printf("\t %10s", p->name);
printf("\t %10s", p->mob_no);
printf("\t %05.2f", p->salary);
printf("\t ");
for (j = 0; j < 5; j++) {
if (p->proj[j] == 1)
printf(" %d,", j + 1);
}
}
void modify_rec(emp_node *p) //modifying a record
{
int j, cho;
char ch1, edt;
do {
printf(
"\n\t1. Name\n\t2. Email Address\n\t3. Mobile No.\n\t4. Salary\n\t5. Date of birth\n\t6. Projects\n");
printf("Enter your choice : ");
scanf("%d", &cho);
switch (cho) {
case 1:
printf("\n\tPrevious name:%s", p->name);
printf("\n\tDo you want to edit ? (y/n)");
getchar();
scanf("%c", &ch1);
if (ch1 == 'y' || ch1 == 'Y') {
printf("\n\tEnter New Name:");
read_name(p);
}
break;
case 2:
printf("\n\tPrevious Mobile No. : %s", p->mob_no);
printf("\n\tDo you want to edit ? (y/n)");
getchar();
scanf("%c", &ch1);
if (ch1 == 'y' || ch1 == 'Y') {
printf("\n\tEnter New Mobile No. :");
read_mob(p);
}
break;
case 3:
printf("\n\tPrevious salary is : %f", p->salary);
printf("\n\tDo you want to edit ? (y/n)");
getchar();
scanf("%c", &ch1);
if (ch1 == 'y' || ch1 == 'Y') {
printf("\n\tEnter New salary:");
scanf("%f", &(p->salary));
}
break;
case 4:
printf("the employee is currently working on project no. ");
for (j = 0; j < 5; j++) {
if (p->proj[j] == 1)
printf(" %d,", j + 1);
}
printf("\n\tDo you want to edit ? (y/n)");
getchar();
scanf("%c", &ch1);
if (ch1 == 'y' || ch1 == 'Y') {
printf(
"\n\tEnter \"1\" for the projects employee is working on : \n");
for (j = 0; j < 5; j++) {
printf("\n\t\tProject No. %d : ", j + 1);
scanf("%d", &(p->proj[j]));
while (p->proj[j] != 1) {
printf("\n\nInvalid entry!! Please re-enter.");
printf("\n\t\tProject No. %d : ", j + 1);
scanf("%d", &(p->proj[j]));
}
}
}
break;
default:
printf("\n\nInvalid Choice!! Please Try again.");
}
printf("\n\nDo you want to edit any other fields ?(y/n)");
getchar();
scanf("%c", &edt);
} while (edt == 'y' || edt == 'Y');
}
emp_node* delete_rec(emp_node *head, int id) //physical deletion of record
{
emp_node *p = head, *q;
if (head->emp_id == id) {
head = head->next;
free(p);
return head;
} else {
q = p->next;
while (q->emp_id != id) {
p = p->next;
q = q->next;
}
if (q->next == NULL)
p->next = NULL;
else
p->next = q->next;
free(q);
return head;
}
}
void display_rev(emp_node *head) {
emp_node *p=head, *q;
while(p->next != NULL)
p=p->next;
while(p!=head || p==head){
q=head;
display_rec(p);
while(q->next != p)
q=q->next;
p=q;
}
}
答案 0 :(得分:2)
我知道这是“作弊”,但你可以这样做:
void display_rev(emp_node *head) {
if (head->next != null)
{
display_rev(head->next);
}
display_rec(head);
}
这是如何工作的:这个例程递归列表中的每个元素直到它结束,然后当它“展开”备份时它会打印每个元素。
void display_rev(emp_node *head) {
emp_node *p=head, *q;
if (p == null) return;
while(p->next != NULL)
p=p->next;
while(p != head) {
q=head;
display_rec(p);
while(q->next != p)
q=q->next;
p=q;
}
display_rec(p);
}
答案 1 :(得分:1)
这个测试总是如此
while(p!=head || p==head)
我认为你应该删除p==head
部分
编辑我测试了循环,你还必须添加头部打印:
void display_rev(emp_node *head) {
emp_node *p=head, *q;
while(p->next != NULL)
p=p->next;
while(p!=head) {// || p==head){
q=head;
display_rec(p);
while(q->next != p)
q=q->next;
p=q;
}
display_rec(p); // print the head also
}
分段错误(因为我假设您打算'突然终止')可能是由于某些数据在程序中未正确初始化而引起的......