Краткое содержание
Этот урок открывает седьмой раздел курса, посвящённый тексту и файлам. Он объясняет, для чего нужен раздел: научить обращаться с текстом как с данными, с его настоящей кодировкой, и добиться того, чтобы программа читала и писала файлы, не ломаясь на неправильно сформированном вводе; представляет четыре его урока и нить, которая их связывает; напоминает то, что раздел считает известным, прежде всего то, что символ для машины есть число, а также векторы, записи и функции из разделов 5 и 6; формулирует задачу, которую решает раздел, задачу программы, которая выглядит правильной, но молча теряет данные, останавливается на первой неожиданной строке и неверно измеряет имена, написанные буквами вне ASCII; заранее показывает, что буква не всегда занимает один байт; и показывает, куда он ведёт, в разделе 8 и в курсе «Программирование на C++ II».
Цели обучения
- Описывать последовательность содержания раздела и объяснять, что каждый урок даёт следующему.
- Вспомнить представление символов в виде числовых кодов (урок 2.4) и записывать код в двоичной и шестнадцатеричной системах.
- Заранее понять на примере, что буква не всегда есть один байт и что поэтому считать байты не значит считать буквы.
- Понимать, что ожидается уметь по окончании раздела, и отличать это от того, что будет изучено в следующем разделе и в курсе «Программирование на C++ II».
Входная проверка
Прежде чем проходить раздел, полезно определить исходный уровень. Эта проверка является самопроверкой: она не оценивается, и её единственная цель состоит в том, чтобы направить занятия. Первые шесть вопросов касаются того, что раздел считает известным: кода символа, записи числа в двоичной и шестнадцатеричной системах, битовой маски, обхода вектора с отбором его элементов, того, что происходит, когда чтение получает буквы вместо числа, и определения записи. Следующие четыре затрагивают, в порядке уроков, центральные идеи раздела: что возвращает поиск, который ничего не находит, размер слова с буквой вне ASCII, пустую строку, которая появляется при смешении двух способов чтения, и файл, который не удалось открыть. Никто не обязан уже сейчас правильно ответить на эти четыре вопроса, и в некоторых из них «пока не знаю» является честным ответом: каждый ответ, верный или нет, объясняет суть дела и называет урок, где она разбирается. Те же умения измеряются снова в конце, в уроке итогов.
Перед началом раздела оцени свою отправную точку. Это короткая самопроверка: она не оценивается, а результат хранится только в твоём браузере.
Вопрос 1Из предыдущих разделовЧто выводит
std::println("{:d} {:d}", 'A', 'a');?Считает, что строчные буквы идут сразу за прописными; между ними 32 кода, и среди них есть несколько знаков.Не учитывает, что{:d}требует код; без негоstd::printlnвывела бы букву.Путает порядок: в ASCII у прописных букв коды меньше, чем у строчных.charхранит число, код символа, а{:d}требует вывести это число, а не букву. В ASCII прописные буквы начинаются с 65, а строчные с 97: разница равна 32, то есть одному биту. Урок Текст не сводится к ASCII отталкивается отсюда, чтобы объяснить, что происходит с буквами, которых нет в ASCII.Повторить: Символы, логические значения, преобразования и константы
Вопрос 2Из предыдущих разделовКак записать 233 в двоичной и шестнадцатеричной системах?
Неверно группирует четыре младших бита:1001есть 9, а не 1.Читает биты в обратном порядке, от младшего к старшему.Путает шестнадцатеричную запись с десятичной.. Если сгруппировать биты по четыре справа,1110и1001дают 14 и 9, то естьeи9. Это код буквы «é», и раздел покажет, что в современном текстовом файле этот код хранится не как один байтe9, а как два.Повторить: Целые числа и их представление
Вопрос 3Из предыдущих разделовЧему равно
0xB1 & 0xC0?Путает&с|: побитовое ИЛИ устанавливает старшие биты, а не выделяет их.Считает, что маска ничего не меняет; она сбрасывает шесть младших битов.Путает&с^, исключающим ИЛИ.0xB1есть10110001, а0xC0есть11000000: побитовое И сохраняет только два старших бита0xB1, то есть10. Именно эту маску урок Текст не сводится к ASCII использует, чтобы распознавать байты, продолжающие букву.Повторить: Биты и математическая библиотека
Вопрос 4Из предыдущих разделовЧто выводит
std::vector<int> v{4, 7, 10, 3}; std::vector<int> w{}; for (const int x : v) { if (x % 2 == 0) { w.push_back(x); } } std::println("{}", w);?Обращает условие:x % 2 == 0истинно для чётных.Считает, чтоpush_backкопирует весь вектор или что отбор применяется кvи выводитсяv.Считает, чтоpush_backдобавляет элемент в начало; он добавляется в конец.Цикл обходитvи копирует вwтолько чётные числа, в том порядке, в каком они встречаются;vне меняется. Раздел использует ту же схему с текстом: обойти байты строки и оставить некоторые из них или обойти строки файла и оставить корректные.Повторить: Векторы
Вопрос 5Из предыдущих разделовПосле
int n{-1}; std::cin >> n;пользователь вводитabc. Чему равноnи что происходит с последующими чтениями?Считает, что неудачное чтение не оставляет следов; оно оставляет их в переменной и в состоянии потока.Предполагает, что C++ предупреждает о неверном вводе; программа продолжает работу так, будто чтение прошло успешно.Путает чтение целого числа с чтением символа.Чтение пропускает пробелы, находит букву, с которой не может начинаться число, и терпит неудачу: стандарт устанавливает, что переменная получает 0, буква остаётся в потоке, а поток переходит в состояние ошибки, без всякого сообщения. Урок Надёжное чтение ввода учит отличать эту неудачу от конца данных и восстанавливаться после неё.Повторить: Ввод, вывод и ошибки
Вопрос 6Из предыдущих разделовКакое из следующих определений правильно объявляет запись с названием и годом?
Забывает точку с запятой после закрывающей скобки, первую ошибку того, кто пишет записи; компилятор точно указывает на неё.Разделяет поля запятыми, как элементы списка; каждое поле есть объявление и заканчивается точкой с запятой.Путает запись, поля которой имеют разные типы и имена, с вектором, все элементы которого одного типа.Каждое поле объявляется как переменная, со своим типом, своим именем и своим начальным значением в фигурных скобках, а определение заканчивается точкой с запятой после закрывающей скобки. Урок Текстовые файлы заполняет векторы таких записей строками файла.Повторить: Записи
Вопрос 7Если
sестьstd::string s{"casa azul"};, что возвращаетs.find("x")?Это соглашение других языков;std::size_tне имеет знака, и-1, преобразованное к нему, есть как разnpos, но сравнение результата с-1работает только благодаря этому преобразованию и вызывает предупреждение компилятора.Путает «не найдено» с позицией 0, позицией вхождения в самом начале строки.Это честный ответ: урок 7.1 знакомит сfindиnpos.Вопрос 8Что выводит
std::println("{}", std::string{"año"}.size());в программе, сохранённой в UTF-8, как программы этого курса?Считает буквы;sizeсчитает байты, которыми они записаны.Считает, что каждая буква занимает два байта; буквы из ASCII занимают один.Это честный ответ: урок 7.2 объясняет это байт за байтом.sizeсчитает байты, а не буквы: в испанском слове «año» («год») «a» и «o» занимают по одному байту, а «ñ», которой нет в ASCII, занимает в UTF-8 два. Урок Текст не сводится к ASCII объясняет почему и учит считать буквы.Повторить: Текст не сводится к ASCII
Вопрос 9Программа выполняет
int age{}; std::string name{}; std::cin >> age; std::getline(std::cin, name);, и пользователь вводит36, нажимает Enter, вводитЛеви нажимает Enter. Что остаётся вname?Предполагает, чтоgetlineначинает со следующей строки; чтение начинается там, где остановился>>.Считает, чтоgetlineснова читает то, что>>уже поглотил.Это честный ответ: урок 7.3 начинается с этого дефекта.>>читает 36 и оставляет в потоке следовавший за ним перевод строки;std::getlineчитает до первого перевода строки, то есть до этого, и возвращает то, что было перед ним: ничего. Урок Надёжное чтение ввода объясняет это и устраняет с помощьюstd::ws.Повторить: Надёжное чтение ввода
Вопрос 10Программа выполняет
std::ifstream in{"data.txt"}; int x{-1}; in >> x;, ноdata.txtнет в папке, из которой она запускается. Что происходит?Предполагает, что открытие несуществующего файла есть ошибка, о которой C++ сообщает; программа продолжает работу без предупреждения.Путает открытие для чтения с открытием для записи, которое действительно создаёт файл.Это честный ответ: урок 7.4 начинается с этого контроля.Открытие файла может не удаться, и неудачу видно, только если опросить поток: поэтому перед чтением пишутif (!in). Урок Текстовые файлы превращает этот контроль в правило и объясняет, от какой папки зависит поиск файла.Повторить: Текстовые файлы
Загрузка содержимого…