Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп
Книгу Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп читаем онлайн бесплатно полную версию! Чтобы начать читать не надо регистрации. Напомним, что читать онлайн вы можете не только на компьютере, но и на андроид (Android), iPhone и iPad. Приятного чтения!
Шрифт:
Интервал:
Закладка:
В качестве альтернативы можно было бы сделать так, чтобы функция operator>>(istream& is, Month& m) перед считыванием в цикле присваивала бы объекту m пустой объект.
Month m;
while (is >> m) {
y.month[m.month] = m;
m = Month(); // "Повторная инициализация" объекта m
}
Попробуем применить это.
// открываем файл для ввода:
cout << "Пожалуйста, введите имя файла для ввода n";
string name;
cin >> name;
ifstream ifs(name.c_str());
if (!ifs) error(" невозможно открыть файл для ввода ",name);
ifs.exceptions(ifs.exceptions()|ios_base::badbit); // генерируем bad()
// открываем файл для вывода:
cout << "Пожалуйста, введите имя файла для ввода n";
cin >> name;
ofstream ofs(name.c_str());
if (!ofs) error(" невозможно открыть файл для ввода ",name);
// считываем произвольное количество объектов класса Year:
vector<Year> ys;
while(true) {
Year y; // объект класса Year каждый раз очищается
if (!(ifs>>y)) break;
ys.push_back(y);
}
cout << " считано " << ys.size() << " записей по годам.n";
for (int i = 0; i<ys.size(); ++i) print_year(ofs,ys[i]);
Функцию print_year() мы оставляем в качестве упражнения.
10.11.3. Изменение представления
Для того чтобы оператор >> класса Month работал, необходимо предусмотреть способ для ввода символьных представлений месяца. Для симметрии мы описываем способ сравнения с помощью символьного представления. Было бы слишком утомительно писать инструкции if, подобные следующей:
if (s=="jan")
m = 1;
else if (s=="feb")
m = 2;
...
Это не просто утомительно; таким образом мы встраиваем названия месяцев в код. Было бы лучше занести их в таблицу, чтобы основная программа оставалась неизменной, даже если мы изменим символьное представление месяцев. Мы решили представить входную информацию в виде класса vector<string>, добавив к нему функцию инициализации и просмотра.
vector<string> month_input_tbl; // month_input_tbl[0]=="jan"
void init_input_tbl(vector<string>& tbl)
// инициализирует вектор входных представлений
{
tbl.push_back("jan");
tbl.push_back("feb");
tbl.push_back("mar");
tbl.push_back("apr");
tbl.push_back("may");
tbl.push_back("jun");
tbl.push_back("jul");
tbl.push_back("aug");
tbl.push_back("sep");
tbl.push_back("oct");
tbl.push_back("nov");
tbl.push_back("dec");
}
int month_to_int(string s)
// Является ли строка s названием месяца? Если да, то возвращаем ее
// индекс из диапазона [0:11], в противном случае возвращаем –1
{
for (int i=0; i<12; ++i) if (month_input_tbl[i]==s) return i;
return –1;
}
На всякий случай заметим, что стандартная библиотека С++ предусматривает более простой способ решения этой задачи. См. тип map<string,int> в разделе 21.6.1.
Если мы хотим вывести данные, то должны решить обратную задачу. У нас есть представление месяца с помощью чисел int, и мы хотели бы представить их в символьном виде. Наше решение очень простое, но вместо использования таблицы перехода от типа string к типу int мы теперь используем таблицу перехода от типа int к типу string.
vector<string> month_print_tbl; // month_print_tbl[0]=="January"
void init_print_tbl(vector<string>& tbl)
// инициализируем вектор представления для вывода
{
tbl.push_back("January");
tbl.push_back("February");
tbl.push_back("March");
tbl.push_back("April");
tbl.push_back("May");
tbl.push_back("June");
tbl.push_back("July");
tbl.push_back("August");
tbl.push_back("September");
tbl.push_back("October");
tbl.push_back("November");
tbl.push_back("December");
}
string int_to_month(int i)
// месяцы [0:11]
{
if (i<0 || 12<=i) error("Неправильный индекс месяца.");
return month_print_tbl[i];
}
Для того чтобы этот подход работал, необходимо где-то вызвать функции инициализации, такие как указаны в начале функции main().
// первая инициализация таблиц представлений:
init_print_tbl(month_print_tbl);
init_input_tbl(month_input_tbl);

Задание
1. Разработайте программу, работающую с точками (см. раздел 10.4). Начните с определения типа данных Point, имеющего два члена — координаты x и y.
2. Используя код и обсуждение из раздела 10.4, предложите пользователю ввести семь пар (x,y). После ввода данных запишите их в вектор объектов класса Point с именем original_points.
3. Выведите на печать данные из объекта original_points, чтобы увидеть, как они выглядят.
4. Откройте поток ofstream и выведите все точки в файл mydata.txt. В системе Windows для облегчения просмотра данных с помощью простого текстового редактора (например, WordPad) лучше использовать расширение файла .txt.
5. Закройте поток ofstream, а затем откройте поток ifstream для файла mydata.txt. Введите данные из файла mydata.txt и запишите их в новый вектор с именем processed_points.
6. Выведите на печать данные из обоих векторов.
7. Сравните эти два вектора и выведите на печать сообщение Что-то не так !, если количество элементов или значений элементов в векторах не совпадает.
Контрольные вопросы
1. Насколько разнообразными являются средства ввода и вывода у современных компьютеров?
2. Что делает поток istream?
3. Что делает поток ostream?
4. Что такое файл?
5. Что такое формат файла?
6. Назовите четыре разных типа устройств для ввода и вывода данных из программ.
7. Перечислите четыре этапа чтения файла.
8. Перечислите четыре этапа записи файлов.
9. Назовите и определите четыре состояния потоков.
10. Обсудите возможные способы решения следующих задач ввода.
10.1. Пользователь набрал значение, выходящее за пределы допустимого
Прочитали книгу? Предлагаем вам поделится своим отзывом от прочитанного(прослушанного)! Ваш отзыв будет полезен читателям, которые еще только собираются познакомиться с произведением.
Уважаемые читатели, слушатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.
- 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
- 2. Просьба отказаться от оскорблений, угроз и запугиваний.
- 3. Просьба отказаться от нецензурной лексики.
- 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.
Надеемся на Ваше понимание и благоразумие. С уважением, администратор knigkindom.ru.
Оставить комментарий
-
Гость Татьяна24 сентябрь 22:20 Как то не очень... Невеста по ошибке. Я не дам тебе развод - Майя Линн
-
Римма24 сентябрь 21:52 Почему главные героинитпкие идиотки? И сюжет не плохой, и написано хорошо. Но как героиня - так дура дурой.... Хозяйка маленького дома, или Любимая для дракона - Кира Рамис
-
Римма20 сентябрь 12:27 Много ненужных пояснений и отступлений. Весь сюжет теряет свою привлекательность. Героиня иногда так тупит, что читать не... Хозяйка приюта для перевертышей и полукровок - Елена Кутукова