C++. Сборник рецептов
Шрифт:
#include <cstdlib>
#include <string>
#include <cctype>
#include <functional>
using namespace std;
void textWrap(istream& in, ostream& out, size_t width) {
string tmp;
char cur = '\0';
char last = '\0';
size_t i = 0;
while (in.get(cur)) {
if (++i == width) {
ltrimws(tmp); // ltrim
как в рецепте
out << '\n' << tmp; // 4.1
i = tmp.length;
tmp.clear;
} else if (isspace(cur) && // Это конец
!isspace(last)) { // слова
out << tmp;
tmp.clear;
}
tmp += cur;
last = cur;
}
}
int main(int argc, char** argv) {
if (argc < 3)
return(EXIT_FAILURE);
int w = 72;
ifstream in(argv[1]);
ofstream out(argv[2]);
if (!in || !out)
return(EXIT_FAILURE);
if (argc == 4) w = atoi(argv[3]);
textWrap(in, out, w);
out.close;
if (out)
return(EXIT_SUCCESS);
else
return(EXIT_FAILURE);
}
Обсуждение
textWrap
читает по одному символы из входного потока. Каждый символ добавляется к временной строке tmp
до тех пор, пока не будет достигнут конец слов или максимальная длина строки. Если достигнут конец слова, а максимальная длина строки еще не достигнута, то временная строка записывается в выходной поток. В противном случае, если максимальная длина строки была превышена, в выходной поток записывается новая строка, пробел в начале временной строки удаляется, и строка записывается в выходной поток. Таким образом, textWrap
записывает в выходной поток столько, сколько можно, но не превышая максимальной длины строки. Вместо разделения слов она переносит все слово на новую строку. Пример 4.25 использует потоки почти так же, как и рецепт 4.15. За дополнительной информацией о потоках и их использовании обратитесь к этому рецепту.
Смотри также
Рецепт 4.15.
4.17. Подсчет числа символов, слов и строк в текстовом файле
Проблема
Требуется подсчитать число символов, слов и строк — или каких-либо других элементов текста — в текстовом файле.
Решение
Для
countStuff
, которая именно это и делает. Пример 4.26. Подсчет статистики по текстовому файлу
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cctype>
using namespace std;
void countStuff(istream& in,
int& chars, int& words, int& lines) {
char cur = '\0';
char last = '\0';
chars = words = lines = 0;
while (in.get(cur)) {
if (cur == '\n' ||
(cur == '\f' && last == '\r'))
lines++;
else chars++;
if (!std::isalnum(cur) && // Это конец
std::isalnum(last)) // слова
words++;
last = cur;
}
if (chars > 0) { // Изменить значения слов
if (std::isalnum(last)) // и строк для специального
words++; // случая
lines++;
}
}
int main(int argc, char** argv) {
if (argc < 2)
return(EXIT _FAILURE);
ifstream in(argv[1]);
if (!in)
exit(EXIT_FAILURE);
int c, w, l;
countStuff(in, c, w, l);
cout << "символов: " << c << '\n';
cout << "слов: " << w << '\n';
cout << "строк: " << l << '\n';
}
Обсуждение
Этот алгоритм очень прост. С символами все просто: увеличивайте счетчик символов при каждом вызове
get
для входного потока. Со строками все не намного сложнее, так как способ представления концов строк зависит от операционной системы. К счастью, обычно это либо символ новой строки (\n
), либо последовательность из символов возврата каретки и перевода строки (\r\n
). Отслеживая текущий и предыдущий символы, можно легко обнаружить вхождения этой последовательности. Со словами все проще или сложнее, в зависимости от определения того, что такое «слово».
Поделиться:
Популярные книги
Инвестиго, из медика в маги 2
2. Инвестиго
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Конструктор
1. Переломный век
Фантастика:
попаданцы
альтернативная история
4.50
рейтинг книги
Блуждающие огни 4
4. Блуждающие огни
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Ох уж этот Мин Джин Хо 1
1. Мин Джин Хо
Фантастика:
попаданцы
5.00
рейтинг книги
Черный Маг Императора 11
11. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга ХIV
14. РОС: Кодекс Крови
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Девочка для Генерала. Книга первая
1. Любовь сильных мира сего
Любовные романы:
остросюжетные любовные романы
эро литература
4.67
рейтинг книги
Ты не мой Boy 2
6. Самбисты
Любовные романы:
современные любовные романы
короткие любовные романы
5.00
рейтинг книги
Брачный сезон. Сирота
Любовные романы:
любовно-фантастические романы
7.89
рейтинг книги
Вор (Журналист-2)
4. Бандитский Петербург
Детективы:
боевики
8.06
рейтинг книги
Наследник павшего дома. Том IV
4. Расколотый мир
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Адвокат Империи 2
2. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Законы Рода. Том 6
6. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Барон Дубов 4
4. Его Дубейшество
Фантастика:
юмористическое фэнтези
аниме
сказочная фантастика
фэнтези
5.00