Как это сделать с помощью std::vector
Во-первых, некоторые из них включают:
#include <vector> // obviously. Can't do vectors without the vector header.
#include <limits> // for a trick I'll use later
Создайте структуру, чтобы связать название товара с ценой
struct item
{
string name;
double price;
};
и сделать вектор этой структуры
vector<item> items;
Затем, после того как вы прочитаете имя и цену, вставьте их в структуру и вставьте структуру в вектор.
item temp;
temp.name = item_name;
temp.price = price;
items.push_back(temp);
О том, почему цикл while
не работает... Это будет прогулка.
while(item_name != SENTINEL)
Это хорошее начало. Если item_name
не SENTINEL
, продолжайте. Абсолютно верно. Дело в том, что item-name не было установлено в первый раз, когда вы попали сюда, заставляя некоторую беличью логику внутри цикла. Общее эмпирическое правило: прочитайте, затем проверьте. Тестировать перед чтением не так уж и полезно. Во-первых, тестировать нечего, но настоящая проблема в том, что теперь вы используете непроверенные данные или вам нужно включить еще один тест, чтобы их отловить.
Прочитай, а потом тестируй.
{
cout<<"Enter the name of the item."<<'\n';
cin>>item_name;
Получить имя элемента. Заводной.
if (item_name == SENTINEL)
{
cin>>item_name;
ХОРОШО. Неплохо, но зачем здесь еще одно item_name?
myfile<<"Thank you for your entries"<<'\n';
myfile<<item_name<<"#"<<price<<endl;
myfile.close();
break;
break
выходит из цикла или switch
. Итак, выходим.
}
else
{
cout<<"Enter the price of the item."<<'\n';
cin>>price;
Чтение числовых значений имеет несколько опасностей, которых вы должны остерегаться. Большой из них заключается в том, что если что-то, что набрал пользователь, не может быть преобразовано в price
, cin
переходит в режим ошибки и не вернется, пока ошибка не будет устранена. И прежде чем пытаться снова получить цену, нужно удалить мусорные данные.
Прелесть функции cin >> x
в том, что она возвращает cin
. Это позволяет складывать команды. cin>>a>>b>>c>>d
. cin
и все его потоковые собратья имеют встроенный логический оператор, который можно использовать в тестах. Если cin
все еще находится в хорошем состоянии, все операции чтения завершены успешно, его можно протестировать, и он вернет true
.
Это позволяет вам делать такие вещи, как if (cin>>a>>b>>c>>d)
, и проверять, что все чтения были хорошими за один раз.
}
}
Применив read, затем test, получаем
while(cin>>item_name && // read in an item name
item_name != SENTINEL) // and then test that it isn't the sentinel
Этот глупо выглядящий фрагмент кода — самый безопасный способ сделать это. Он даже поймает и выход cin
внезапно закончится. С cin
такое случается не так часто, но это отличный способ проверить конец файла.
{
while (!(cin >> price)) // keep looping until the user gives a number
{ // if we're here, the user didn't give a good number and we have to clean up
// after them. Bad user. Bad. Bad.
Кроме того, не делайте этот трюк с файлом. Файл мог закончиться. Вам нужно будет проверить файл на конец файла и выйти здесь, прежде чем продолжить очистку.
// clear the error
cin.clear();
// throw out everything the user's typed in up to the next line
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
// user got out of the while of doom. They must have entered a number.
На самом деле, это просто должно было начинаться с числа. cin >>
довольно тупой и пропустит 1234abcd, взяв 1234 и оставив abcd для следующего чтения. Это может преподнести вам неприятные сюрпризы. В этом случае abcd станет следующим item_name
. то, что должно было стать следующим item_name
, станет следующим price
, и оттуда покатится плохое джу-джу.
А теперь вернемся к коду.
item temp; // make a temporary item
temp.name = item_name; // set the values correctly
temp.price = price;
items.push_back(temp); // put them in the list.
Здесь вы можете немного сэкономить, добавив конструктор в item
и используя метод emplace_back
из vector
. Поищи это. Очень удобно.
}
И снова без беглого комментария:
while(cin>>item_name && // read in an item name
item_name != SENTINEL) // and then test that it isn't the sentinel
{
while (!(cin >> price)) // keep looping until the user gives a number
{ // if we're here, the user didn't give a good number and we have to clean up
// after them. Bad user. Bad. Bad.
// clear the error
cin.clear();
// throw out everything the user's typed in up to the next line
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
// user got out of the while of doom. They must have entered a number.
item temp; // make a temporary item
temp.name = item_name; // set the values correctly
temp.price = price;
items.push_back(temp); // put them in the list.
}
Теперь у вас есть vector
полный item
s для печати. В Stack Overflow полно примеров того, как это сделать, но лучше сначала попробовать.
person
user4581301
schedule
13.02.2016