C ++ - Строковый ввод с указателем на структуру? - PullRequest
1 голос
/ 08 февраля 2010

Как вы используете указатель на структуру, чтобы получить ввод, который будет храниться в строковой переменной? Я думал, что просто передача pz-> szCompany в getline () будет вести себя так же, как если бы я использовал. оператор обычного экземпляра Pizza (вместо указателя на), но когда я запускаю эту программу, она полностью пропускает подсказку с названием компании.

// 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;

Ответы [ 3 ]

7 голосов
/ 08 февраля 2010

Когда вы используете >> для чтения ввода, он оставит непрочитанные символы в потоке (те, которые не могут быть преобразованы в целое число, по крайней мере, символ возврата, который вы вводите для ввода), который следующий getline будет потреблять, думая, что он уже прочитал (пустую) строку.

#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);

Ваша проблема не имеет ничего общего со структурой или указателями, просто нормальное поведение входных потоков.

Возможно, вам также придется иметь дело с неправильным вводом. Например, если ввести не-число, где ожидается число, то поток будет переведен в состояние ошибки, так что все последующие попытки чтения потерпят неудачу, если вы не справитесь с этим. Лучше прислушайтесь к совету Нейла, но для получения ввода от пользователя может также иметь смысл использовать функцию для форматированного ввода, которая запрашивает у вас, пока вы не получите действительный ввод:

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: ");
2 голосов
/ 08 февраля 2010

Добавить либо:

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

или

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

Ваша проблема связана с буферизацией потока

2 голосов
/ 08 февраля 2010

Это не имеет ничего общего с указателем на экземпляр структуры. Просто не очень хорошая идея смешивать ввод строки с форматированным вводом. На самом деле, вообще не рекомендуется использовать форматированный ввод из потока интерактивного ввода. Вместо этого вы должны прочитать каждый ввод, используя getline (), а затем преобразовать в требуемый тип.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...