-3

I have class

class Item
{
    private:
        string name;

    public:
        void set_data()
        {
            getline(cin, name);
        }
}

From the main function I am setting the value of the name once, but when I want to give it another value, I can't. I mean that the second time when I call the function from the same object, it does nothing.

CodingLumis
  • 420
  • 2
  • 19
14DENDIK
  • 9
  • 7
  • Your function `set_data` doesn't only set the member `name`, it also read from standard input. If you don't give some input, then `std::getline` will wait forever. – Some programmer dude Jun 08 '18 at 11:03
  • 2
    One possible reason could be that you also do something else in main: [Why does std::getline() skip input after a formatted extraction?](https://stackoverflow.com/questions/21567291/why-does-stdgetline-skip-input-after-a-formatted-extraction) – Bo Persson Jun 08 '18 at 11:17
  • @14DENDIK there is nothing wrong. see this : https://www.ideone.com/bqJvc2 I don't know your rest of the code, so can not say anything. – JeJo Jun 08 '18 at 11:26
  • 1
    The problem will lie in what you're not showing in between the two calls. How is `std::cin` being used? – acraig5075 Jun 08 '18 at 11:50

1 Answers1

-3

First of all, in C++ your implementation should be separate from the declaration unless you are using templates which you are not. This is not Java.

Second, your sample code is missing a closing brace. I have submitted an edit to add it and improve your code formatting.

That aside, the following implementation works for me:

Item.h

class Item
{
private:
    std::string name;

public:    
    void set_data();
    void printName();
};

Item.cpp

void Item::set_data()
{
    std::cout << "Type name and hit return: " << std::endl;
    getline(std::cin, name);
}

void Item::printName()
{
    std::cout << "Name is : " << name << std::endl;
}

main.cpp

// Entry point
int main(int argc, char** argv)
{
    // Yes I thought I would mix things up and use new instead of Item i; So shoot me.
    Item * i = new Item();

    i->set_data();
    i->printName();

    i->set_data();
    i->printName();

    delete i;

    return 0;
}

The application will wait at both calls to set_data() for me to type something in and hit return. Then it continues as normal. I added a text prompt so it is less confusing to see in the console. I get this:

enter image description here

Does this in some way answer your question? If you are doing something else in main() then try stripping it out back to just this simple action then add the other stuff back in until you find the bit that introduces the problem.

UPDATE: As prompted by the comments below, if you put std::cin >> before another call to getline() it will read the first word from the stream and leave the rest of your string and the \n character in there which getline() uses for its delimiter. So next time you call getline() it will automatically extract the rest of the string from the stream without requesting user input. I guess this is probably what you are seeing.

J. Doe
  • 285
  • 1
  • 11
CodingLumis
  • 420
  • 2
  • 19
  • 2
    You have this: `Item * i = new Item();` which we have to `delete ` after. However, I do not understand, why you need a heap allocation to demonstrate this. – JeJo Jun 08 '18 at 11:29
  • 1
    One question, why you create an object as a pointer? – 14DENDIK Jun 08 '18 at 11:29
  • 1
    Do some other `cin` input between the two `set_data` calls. – acraig5075 Jun 08 '18 at 11:29
  • Wow, I guess the pointer police really spat out their dummy with this one. Does it really matter for a MWE whether I use `new` and `delete` or automatic storage, jeez?! – CodingLumis Jun 08 '18 at 11:39
  • @acraig5075 by all means add another `getline()` call in the main method if you want. It will still behave as you expect it to and wait for input before continuing to the second `set_data()` call. – CodingLumis Jun 08 '18 at 11:41
  • @CodingLumis Try this in between the two calls `int x; cin >> x;` – acraig5075 Jun 08 '18 at 11:48
  • @14DENDIK because I felt like it really but I suppose, I can invent a legitimate reason if you want like the programmer might want a destructor to be called at application exit which will only be guaranteed with a manual call to `delete`. The OS won't necessarily call a destructor on objects allocated on the stack at `main()` scope. – CodingLumis Jun 08 '18 at 11:51
  • @acraig5075 but then the `>>` will leave the `\n` in the stream screwing over the next `getline()` call which relies on that for its delimiter. I f this is what you are getting at then I'll update the answer. – CodingLumis Jun 08 '18 at 11:58
  • @CodingLumis Yes, and that is my point, the question can't be answered because it doesn't give enough information. As it stands it's all guesswork. The question should get closed giving the person a chance to improve it. – acraig5075 Jun 08 '18 at 12:06
  • @CodingLumis Ummm, of course the OS doesn't call destructors at the end of main. For an automatic variable initialized in some block scope or another, a C++ compiler sticks a destructor call at the end of that block scope. And that includes `main`. 14DENDIK is a young and impressionable noob and we shouldn't give them any wrong ideas about memory management. – hegel5000 Jun 08 '18 at 12:38
  • 1
    @CodingLumisb the only difference between using automatic storage here and using `new` and `delete` is that the latter is not exception safe and makes the code confusing and harder to get right. There is no reason to not use automatic storage here. – Kevin Jun 08 '18 at 12:56