0

I am currently working on a very simple project and I found a problem in the testing phase when I tried to enter his name for the new employee and the decision condition was suddenly triggered, I am not sure why this happened. Based on my limited coding experience, in general, a statement in an output judgment statement needs to fulfil a judgment condition, but why would a judgment condition be triggered if I didn't do any input? Thank you all for your help.

Here is a part of the code.

void Management::Add_Staff() {
 std::cout << "Please enter the number of staffs you want to add: " << std::endl;
 int addNum = 0;  // saves the amount entered by the user
 std::cin >> addNum;
 while (addNum <= 0 || addNum >= 50) {
   std::cout << "Invaild number. Please try again" << std::endl;
   std::cout << "Please enter the number of staffs you want to add: " << std::endl;
   std::cin.clear(); // clear error enter
   std::cin.ignore(INT_MAX, '\n'); // INT_MAX means an extremely large number,'\n' means empty space
   std::cin >> addNum;
 }

   int new_Size = this->_StaffNumber + addNum;  // The number of existing employees plus
                                  // the number of new employees
   Person** new_Space = new Person*[new_Size];  // Open up new space
   if (this->_StaffArray !=
       NULL)  // if the data of the original pointer is not null
   {
     for (int i = 0; i < this->_StaffNumber;
          i++)  // data of the original pointer is added to the new pointer
     {
       new_Space[i] = this->_StaffArray[i];
     }
   }

   for (int i = 0; i < addNum; i++) {
     int ID;  // create an variable nameed id to store the staff number entered
           // from users           
     std::cout << "Please enter pure and positive number as the staff number of " << i + 1 << " staff: " << std::endl;
     std::cin >> ID;
     while (ID <= 0) {
       std::cout << "Invalid staff number, please enter again: " << std::endl;
       std::cin.clear(); 
       std::cin.ignore(INT_MAX, '\n'); 
       std::cin >> ID;
     }
     std::string NAME;  // create an variable nameed id to store the staff
                     // number entered from users
     std::cout << "Please enter the name: " << std::endl;
     // std::cin >> NAME;
     while (std::getline(std::cin, NAME)) {
       if (NAME.length() == 0)
       {
           std::cout << "Your input is not correct. Please re-enter your name" << 
std::endl;
       }

       // This will check if the NAME contains only characters.
       else if (std::all_of(NAME.begin(), NAME.end(), isalpha)) // isalpha: The function returns a non-zero value if the argument is an alphabetic character, or zero otherwise.
       {
           break;
       }
       else {
           std::cout << "Only characters are allowed:" << std::endl;
       }
   }

That is my test case.

*********************************************************

********Welcome to the employee management system********

***********0.Exit the management page********************

***********1.Add the employee information****************

***********2.Display the employee information************

***********3.Delete the employee information*************

***********4.Modify the employee information************
 
***********5.Search the employee information************

***********6.Sort by number***************************** 

Please enter the numbers 0 through 6 as your next step
 
1

Please enter the number of staffs you want to add:

1

Please enter pure and positive number as the staff number of 1 staff:
 
12

Please enter the name: 

Your input is not correct. Please re-enter your name

After I entered the employee number, the judgment condition was triggered before I entered the name, but I didn't enter a space, I didn't even have time to enter something, and the judgment condition was triggered.

Sebastian
  • 1,834
  • 2
  • 10
  • 22
Cedric xu
  • 13
  • 5
  • It is not a C code. – Vlad from Moscow May 20 '22 at 23:03
  • Before calling getline you need to call the member function ignore to remove the new line character stored in the input buffer similarly to what you already did std::cin.ignore(INT_MAX, '\n'); – Vlad from Moscow May 20 '22 at 23:08
  • @Vlad from Moscow Ignore is a function I googled. Am I not quite sure how to call the member function at exactly where before calling getLine, just before printf()? – Cedric xu May 20 '22 at 23:12
  • Before this statement while (std::getline(std::cin, NAME)) { – Vlad from Moscow May 20 '22 at 23:14
  • Does this answer your question? [Why does std::getline() skip input after a formatted extraction?](https://stackoverflow.com/questions/21567291/why-does-stdgetline-skip-input-after-a-formatted-extraction) – Retired Ninja May 20 '22 at 23:16
  • @Vlad from Moscow I tried but it didn't solve the problem. here is my new code. std::string NAME; // create an variable nameed id to store the staff // number entered from users std::cout << "Please enter the name: " << std::endl; // std::cin >> NAME; std::cin.ignore(INT_MAX, '\n'); while (std::getline(std::cin, NAME)) { – Cedric xu May 20 '22 at 23:18
  • @Vlad from Moscow I already removed it, but it still does not work well I thought. – Cedric xu May 20 '22 at 23:23
  • @Retired Ninja I read the post, but the method of the post didn't help me solve the problem – Cedric xu May 20 '22 at 23:30
  • The solution is to add `std::cin.ignore(INT_MAX, '\n');` after you use formatted input `>>` and before you use `getline`. This is a very common problem. If you're still having issues after doing that you might consider extracting the code you've shown into a [mcve] so we can see the full picture and also copy/paste/compile/run to see the problem. – Retired Ninja May 20 '22 at 23:32

1 Answers1

0

When you get input form the user using std::cin the input from the user does not go directly into the program. Instead that input sits in a buffer, which temperately stores that user entered data so you can later tie that data to a variable or perform some other task with that data. However, if that buffer does not get cleared and you use std::getline then std::getline will read the buffer instead of the new user input that you actually wanted. This is why its important to make use of the std::cin.ignore() function, which will clear the buffer of unwanted int and characters. If you want a more en-depth overview of std::cin.ignore() check out this link .

The Fix:

Looking at your code you do make use of cin.ignore() to clear the buffer but only the user enters something other then a number which will drop them into that while loop.

This is what you currently have:

    while (ID <= 0) {
    std::cout << "Invalid staff number, please enter again: " << std::endl;
    std::cin.clear(); 
    std::cin.ignore(INT_MAX, '\n'); 
    std::cin >> ID;
}
std::string NAME;  // create an variable named id to store the staff
 // number entered from users
std::cout << "Please enter the name: " << std::endl;

To correct this you will need that std::cin.ignore() call out side of the while loop so that it always happens whether there is an error or not. I have a comment that says NEW CODE LINE for where I made the change.

while (ID <= 0) {
    std::cout << "Invalid staff number, please enter again: " << std::endl;
    std::cin.clear();
    std::cin.ignore(INT_MAX, '\n');  
    std::cin >> ID;
}

std::cin.ignore(INT_MAX, '\n');//NEW CODE LINE

std::string NAME;  // create an variable named id to store the staff 
//number entered from users
std::cout << "Please enter the name: " << std::endl;