views:

283

answers:

3

How do you use a pointer-to-struct to get input that will be stored in a string variable? I thought simply passing pz->szCompany to getline() would behave the same as if I had used the . operator on a normal instance of Pizza (instead of a pointer-to), but when I run this program it skips over the company name prompt completely.

// Parts of the program omitted.
struct Pizza {
    string szCompany;
    float diameter;
    float weight;
};
Pizza* pz = new Pizza;

cout << "Enter the weight: ";
cin >> pz->weight;

cout << "Enter the company name: ";
// use getline because the company name can have spaces in it.
getline(cin, pz->szCompany);

cout << "Enter the diameter: ";
cin >> pz->diameter;

cout << "\nCompany name: " << pz->szCompany;
cout << "\nWeight: " << pz->weight;
cout << "\nDiameter: " << pz->diameter;

// cannot forget this step.
delete pz;
return 0;
+2  A: 

This has nothing to do with the pointer to the structure instance. It is simply not a good idea to mix line input with formatted input. In fact, it's not a good idea to use formatted input from an interactive input stream at all. You should instead read each input using getline() and then convert to the required type.

anon
+2  A: 

Add either:

cout << "Enter the company name: " << std::endl;

or

cout << "Enter the company name: ";
cout.flush();

You problem concerned with bufferization of stream

Dewfy
I was under the impression that cout and cin were automatically syncronized anyway.
visitor
+8  A: 

When you use >> to read input, it will leave unread characters in the stream (those, that couldn't be converted to integer, at least the return character you type to enter input), which the following getline will consume thinking it has already read an (empty) line.

#include <limits>

//...
cin >> pz->diameter;
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

cout << "Enter the company name: ";
// use getline because the company name can have spaces in it.
getline(cin, pz->szCompany);

Your problem has nothing to do with the struct or pointers, just the normal behavior of input streams.

You may also have to deal with incorrect input. For example, entering a non-number where a number is expected would put the stream in an error state, so that all subsequent attempts to read would fail unless you deal with it. Better take Neil's advice, but for getting input from the user, it might also make sense to use a function for formatted input that prompts you until you get valid input:

template <class T>
T input(const std::string& prompt, const std::string& error_prompt)
{
    std::cout << prompt;
    T result;
    while (!(std::cin >> result)) {
        std::cin.clear();
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        std::cout << error_prompt;
    }
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    return result;
}

//...
pz->weight = input<float>("Enter the weight: ", "Please enter a numeric value: ");
visitor
Thanks for the answer. I managed to fix this by doing "char dummy; ... cin >> pz->diameter; cin.get(dummy);" to clear the newline, instead of using <limits>.
cornjuliox
The problem with that is that the user might type more than just a newline, e.g spaces or other non-convertible characters.
visitor
@cornjuliox - You might consider reading this: http://www.daniweb.com/forums/thread90228.html#
Manuel
@Manuel - thanks, I'm reading it right now.
cornjuliox