Программирование. Принципы и практика использования C++ Исправленное издание, стр. 163
Punct_stream ps(cin); // объект ps считывает данные из потока cinps.whitespace(";:."); // точка с запятой, двоеточие и точка // также являются разделителямиps.case_sensitive(false); // нечувствительный к региструОчевидно, что наиболее интересной операцией является оператор ввода
>>istreamline' 'stringstreambufferbuffer>>bufferPunct_stream& Punct_stream::operator>>(string& s){ while (!(buffer>>s)) { // попытка прочитать данные // из потока buffer if (buffer.bad() || !source.good()) return *this; buffer.clear(); string line; getline(source,line); // считываем строку line // из потока source // при необходимости заменяем символы for (int i =0; i<line.size(); ++i) if (is_whitespace(line[i])) line[i]= ' '; // в пробел else if (!sensitive) line[i] = tolower(line[i]); // в нижний регистр buffer.str(line); // записываем строку в поток } return *this;}Рассмотрим этот код шаг за шагом. Сначала обратим внимание не нечто необычное.
while (!(buffer>>s)) {Если в потоке
bufferistringstreambuffer>>ssbufferbuffer>>s!(buffer>>s)buffersourcebuffer>>sbufferwhile (!(buffer>>s)) { // попытка прочитать символы из буфера if (buffer.bad() || !source.good()) return *this; buffer.clear(); // заполняем объект buffer}Если объект
bufferbad()bufferbuffereof()buffer;bufferstring line;getline(source,line); // вводим строку line из потока source // при необходимости выполняем замену символовfor (int i =0; i<line.size(); ++i) if (is_whitespace(line[i])) line[i]= ' '; // в пробел else if (!sensitive) line[i] = tolower(line[i]); // в нижний регистр buffer.str(line); // вводим строку в потокСчитываем строку в объект
bufferis_whitespace()Punct_streamtolower()AaПосле правильной обработки строки
lineistringstreambuffer.str(line);bufferistringstreamlineОбратите внимание на то, что мы “забыли” проверить состояние объекта
sourcegetline()!source.good()