简体   繁体   English

在C语言中,为什么尽管在代码中提到了我在链表节点内部的scanf输入也没有被获取的原因?

[英]In C,why is my scanf input inside of a linked list node not being taken despite being mentioned in code?

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#define MAX 30

struct EMP {
    int empno;
    char empName[MAX];
    char designation[MAX];
    struct EMP *next;
};

/*********************************************************************/
/* Function to insert a node at the front of the linked list.        */
/* front: front pointer, id: employee ID, name: employee name        */
/* desg: Employee designation                                        */
/* Returns the new front pointer.                                    */
/*********************************************************************/

struct EMP *insert(struct EMP *front, int id, char name[], char desg[])
{
    struct EMP *newnode;

    newnode = (struct EMP *)malloc(sizeof(struct EMP));

    if (newnode == NULL) {
        printf("\nAllocation failed\n");
        exit(2);
    }
    newnode->empno = id;
    strcpy(newnode->empName, name);
    strcpy(newnode->designation, desg);
    newnode->next = front;
    front = newnode;
    return (front);
}                               /* End of insert() */

/* Function to display a node in a linked list */
void printNode(struct EMP *p)
{
    printf("\nEmployee Details...\n");
    printf("\nEmp No : %d", p->empno);
    printf("\nName : %s", p->empName);
    printf("\nDesignation : %s\n", p->designation);
    printf("-------------------------------------\n");
}                               /* End of printNode() */

/* ******************************************************* */
/* Function to deleteNode a node based on employee number */
/* front: front pointer, id: Key value */
/* Returns: the modified list. */
/* ******************************************************* */

struct EMP *deleteNode(struct EMP *front, int id)
{
    struct EMP *ptr;
    struct EMP *bptr;           /* bptr is pointing to the node behind ptr */

    if (front->empno == id) {
        ptr = front;
        printf("\nNode deleted:");
        printNode(front);
        front = front->next;
        free(ptr);
        return (front);
    }
    for (ptr = front->next, bptr = front; ptr != NULL; ptr = ptr->next, bptr = bptr->next) {
        if (ptr->empno == id) {
            printf("\nNode deleted:");
            printNode(ptr);
            bptr->next = ptr->next;
            free(ptr);
            return (front);
        }
    }
    printf("\nEmployee Number %d not found ", id);
    return (front);
}                               /* End of deleteNode() */

/*****************************************************************/
/* Function to search the nodes in a linear fashion based emp ID */
/* front: front pointer, key: key ID. */
/*****************************************************************/
void search(struct EMP *front, int key)
{
    struct EMP *ptr;

    for (ptr = front; ptr != NULL; ptr = ptr->next) {
        if (ptr->empno == key) {
            printf("\nKey found:");
            printNode(ptr);
            return;
        }
    }
    printf("\nEmployee Number %d not found ", key);
}                               /* End of search() */

/* Function to display the linked list */
void display(struct EMP *front)
{
    struct EMP *ptr;

    for (ptr = front; ptr != NULL; ptr = ptr->next) {
        printNode(ptr);
    }
}                               /* End of display() */

/* Function to display the menu of operations on a linked list */
void menu()
{
    printf("---------------------------------------------\n");
    printf("Press 1 to INSERT a node into the list \n");
    printf("Press 2 to DELETE a node from the list \n");
    printf("Press 3 to DISPLAY the list \n");
    printf("Press 4 to SEARCH the list \n");
    printf("Press 5 to EXIT \n");
    printf("---------------------------------------------\n");
}                               /* End of menu() */

/* Function to select the option */
char option()
{
    char choice;

    printf("\n\n>> Enter your choice: ");
    switch (choice = getche()) {
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
        return (choice);
    default:
        printf("\nInvalid choice.");
    }
    return choice;
}                               /* End of option() */

/* The main() program begins */
void main()
{
    struct EMP *linkList;
    char name[21], desig[51];
    char choice;
    int eno;

    linkList = NULL;

    printf("\nWelcome to demonstration of singly linked list\n");

    menu();                     /* Function call */

    do {
        choice = option();      /* to choose oeration to be performed */

        switch (choice) {
        case '1':
            printf("\nEnter the Employee Number : ");
            scanf("%d", &eno);

            printf("Enter the Employee name : ");
            fflush(stdin);
            gets(name);

            printf("Enter the Employee Designation : ");
            gets(desig);

            linkList = insert(linkList, eno, name, desig);
            break;

        case '2':
            printf("\n\nEnter the employee number to be deleted: ");
            scanf("%d", &eno);

            linkList = deleteNode(linkList, eno);
            break;

        case '3':
            if (linkList == NULL) {
                printf("\nList empty.");
                break;
            }
            display(linkList);
            break;

        case '4':
            printf("\n\nEnter the employee number to be searched: ");
            scanf("%d", &eno);

            search(linkList, eno);
            break;

        case '5':
            break;
        }
    } while (choice != '5');
}                               /* End of main() */

However , when I run the program , the program is not accepting the value for Employee name and directly jumping to Employee designation . 但是,当我运行该程序时,该程序未接受Employee名称的值,而是直接跳转到Employee的名称。

As you can see in the screenshot of the output linked, it is directly jumping to the employee designation without taking input for employee name 正如您在链接的输出的屏幕快照中看到的那样,它直接跳转到员工名称,而无需输入员工姓名

Why is this happening ? 为什么会这样呢?

Edit 1: I was told to try replacing 'gets' with 'fgets' . 编辑1:有人告诉我尝试用'fgets'代替'gets'。 Despite doing that , the computer is still now taking the input for employee name and directly jumping to employee designation 尽管这样做,计算机现在仍在输入员工姓名,并直接跳转到员工指定

  #include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#define MAX 30

struct EMP
{
int empno;
char empName[MAX];
char designation[MAX];
struct EMP *next;
};

/*********************************************************************/
/* Function to insert a node at the front of the linked list. */
/* front: front pointer, id: employee ID, name: employee name */
/* desg: Employee designation */
/* Returns the new front pointer. */
/*********************************************************************/

struct EMP* insert(struct EMP *front, int id, char name[], char desg[])
{
struct EMP *newnode;

newnode = (struct EMP*) malloc(sizeof(struct EMP));

if (newnode == NULL)
{
printf("\nAllocation failed\n");
exit(2);
}
newnode->empno = id;
strcpy(newnode->empName, name);
strcpy(newnode->designation, desg);
newnode->next = front;
front = newnode;
return(front);
} /*End of insert() */

/* Function to display a node in a linked list */
void printNode(struct EMP *p)
{
printf("\nEmployee Details...\n");
printf("\nEmp No : %d", p->empno);
printf("\nName : %s", p->empName);
printf("\nDesignation : %s\n", p->designation);
printf("-------------------------------------\n");
} /*End of printNode() */

/* ********************************************************/
/* Function to deleteNode a node based on employee number */
/* front: front pointer, id: Key value */
/* Returns: the modified list. */
/* ********************************************************/

struct EMP* deleteNode(struct EMP *front, int id)
{
struct EMP *ptr;
struct EMP *bptr; /* bptr is pointing to the node behind ptr */

if (front->empno == id)
{
ptr = front;
printf("\nNode deleted:");
printNode(front);
front = front->next;
free(ptr);
return(front);
}

for(ptr=front->next, bptr=front; ptr!=NULL; ptr=ptr->next, bptr=bptr->next)
{
if (ptr->empno == id)
{
printf("\nNode deleted:");
printNode(ptr);
bptr->next = ptr->next;
free(ptr);
return(front);
}
}
printf("\nEmployee Number %d not found ", id);
return(front);
} /*End of deleteNode() */

/*****************************************************************/
/* Function to search the nodes in a linear fashion based emp ID */
/* front: front pointer, key: key ID. */
/*****************************************************************/
void search(struct EMP *front, int key)
{
struct EMP *ptr;

for (ptr = front; ptr != NULL; ptr = ptr -> next)
{
if (ptr->empno == key)
{
printf("\nKey found:");
printNode(ptr);
return;
}
}
printf("\nEmployee Number %d not found ", key);
} /*End of search() */

/* Function to display the linked list */
void display(struct EMP *front)
{
struct EMP *ptr;

for (ptr = front; ptr != NULL; ptr = ptr->next)
{
printNode(ptr);
}
} /*End of display() */

/* Function to display the menu of operations on a linked list */
void menu()
{
printf("---------------------------------------------\n");
printf("Press 1 to INSERT a node into the list \n");
printf("Press 2 to DELETE a node from the list \n");
printf("Press 3 to DISPLAY the list \n");
printf("Press 4 to SEARCH the list \n");
printf("Press 5 to EXIT \n");
printf("---------------------------------------------\n");
} /*End of menu() */

/* Function to select the option */
char option()
{
char choice;

printf("\n\n>> Enter your choice: ");
switch(choice=getche())
{
case '1':
case '2':
case '3':
case '4':
case '5': return(choice);
default : printf("\nInvalid choice.");
}
return choice;
} /*End of option() */

/* The main() program begins */
void main()
{
struct EMP *linkList;
char name[21], desig[51];
char choice;
int eno;

linkList = NULL;

printf("\nWelcome to demonstration of singly linked list\n");

menu(); /*Function call */

do {
choice = option(); /*to choose oeration to be performed */

switch(choice)
{
case '1':

printf("\nEnter the Employee Number : ");
scanf("%d", &eno);

printf("Enter the Employee name : ");
    //fflush(stdin);
    fgets(name,MAX,stdin);


printf("Enter the Employee Designation : ");
fgets(desig,MAX,stdin);

linkList = insert(linkList, eno, name, desig);
break;

case '2': printf("\n\nEnter the employee number to be deleted: ");
scanf("%d", &eno);

linkList = deleteNode(linkList, eno);
break;

case '3': if (linkList == NULL)
{
printf("\nList empty.");
break;
}
display(linkList);
break;

case '4': printf("\n\nEnter the employee number to be searched: ");
scanf("%d", &eno);

search(linkList, eno);
break;

case '5': break;
}
} while (choice != '5');
} /*End fo main()*/

Answer to the question in the title 回答标题中的问题

Input is not taken because you're mixing the scanf and gets family of functions. 未输入,因为您混用了scanf获得了一系列功能。 scanf leaves the new line character in the buffer, and then when you call fgets to acquire the new line, but fgets finds a new line as the first character and returns immediately. scanf将新行字符scanf在缓冲区中,然后当您调用fgets获取新行时,但是fgets找到新行作为第一个字符并立即返回。

Suggestion 建议

Pick only one of the *get* and *scanf* families to handle your input. 仅选择*get**scanf*系列之一来处理您的输入。 You can still use fgets to get the input, and then pass it to sscanf , to handle the format and retrieve your values. 您仍然可以使用fgets获取输入,然后将其传递给sscanf ,以处理格式并检索您的值。

Example

do {
    choice = option();      /* to choose oeration to be performed */

    char line_buffer[128];  // Declare your own line buffer
    setbuf(stdin, NULL);  // Set stdin to unbuffered

    switch (choice) {
    case '1':
        printf("\nEnter the Employee Number : ");
        // put input into line buffer
        fgets(line_buffer, sizeof(line_buffer), stdin); 
        // use sscanf on your line_buffer instead of stdin
        sscanf(line_buffer, "%d", &eno); 

        printf("Enter the Employee name : ");
        fgets(name, sizeof(name), stdin);

        printf("Enter the Employee Designation : ");
        fgets(desig, sizeof(desig), stdin);

        linkList = insert(linkList, eno, name, desig);
        break;
// ...

The problem here is \\n is in buffer stdin when you are taking input using gets() . 这里的问题是,当您使用gets()进行输入时, \\n在缓冲区stdin gets() reads stdin (if no buffer is specified) buffer till \\n . gets()读取stdin (如果未指定缓冲区)直到\\n

One naive solution would be read an extra character that that will eat up \\n . 一个幼稚的解决方案是读取一个多余的字符,该字符会耗尽\\n The idea is you can use any of the following just after using scanf() to consume \\n from the buffer, 这个想法是,在使用scanf()从缓冲区消耗\\n之后,您可以使用以下任何一种方法,

  1. gets();
  2. getc(stdin);
  3. getchar();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM