1

I wrote the following simple C++ structure implementation to see the usage of pointer to structure.

#include <iostream>

struct Employee
{
    std::string name;
    std::string sex;
    int e_id;
}emp[2];

void printEmployee(struct Employee *e)
{
    std::cout << e->name << std::endl;
    std::cout << e->sex << std::endl;
    std::cout << e->e_id << std::endl;
}

int main(int argc, char const *argv[])
{
    struct Employee *e_ptr;
    e_ptr = emp;

    for (int i = 0; i < 2; ++i)
    {
        std::getline(std::cin, emp[i].name);
        std::getline(std::cin, emp[i].sex);
        std::cin >> emp[i].e_id;
    }

    for (int i = 0; i < 2; ++i)
    {
        printEmployee(e_ptr+i);
        std::cout << std::endl;
    }
    return 0;
}

The inputs are

John Smith
male
123
Sarah Collin
female

After these input the program shows the output although the code is supposed to take one more input. The output is

John Smith
male
123



Sarah Collin
0

But If I don't include int e_id as a member then the code works perfectly.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
MD Abid Hasan
  • 339
  • 1
  • 3
  • 15

2 Answers2

2

This is from mixing getline and cin. Getline reads in the input until it hits a (generally) newline '\n'. It takes everything up to the newline, and throws away the newline.

cin reads until you hit white space (like, say, a newline), but doesn't throw it out of the stream. So, you type in 123 ENTER, meaning you have 123\n in the stream. Cin takes the 123 but leaves the \n.

Now you go back to the getline for employee name and immediately it sees the \n in the stream, which means it's done, and it throws it away. Out of curiosity, does it work if you type 123 SPACE instead of enter?

So what's actually happening is John Smith is good, male is good, 123 is good, but then the second employee's name is skipped, you typed Sarah Collin in for what was technically gender, then typed female for what was supposed to be e_id. Since female isn't an integer, what happens? Cin, by default, enters an error state and skips futher cin operations (you can also configure it to throw an exception). So really you actually never enter anything for the second e_id, and the 0 that you see is what it happened to be when it was created (you never initialized it, so it could actually be ANY value! Reading an uninitialized value is undefined behavior. Your compiler may help you out by setting ints to 0 for you, but that's not a kindness you can count on).

Here's someone else with your problem, and an example of how to use

cin.ignore();

to work around this. You need to manually ignore that newline character.

When and why do I need to use cin.ignore() in C++?

Community
  • 1
  • 1
mock_blatt
  • 955
  • 5
  • 11
2

While reading integer std::cin stops when it encounters a character other than [+][-][0-9]. That is, std::cin stops at a character which cannot be included in a valid representation of an integer.

In the third line of input there are 4 characters are 123\n.

While reading std::string, std::getline stops reading characters when it encounters \n or delim characters. Also, std::getline does not store \n or delim characters in the string which is reads.

So, std::cin reads the integer emp[0].e_id as expected and stops at \n. After this std::getline reads \n and stops and stores nothing in emp[1].name

sameerkn
  • 2,209
  • 1
  • 12
  • 13