нет. Если был то это конец слова, и я увеличиваю счетчик слов. Определить, является ли символ буквенно-цифровым, можно с помощью функции isalnum
из <cctype>
. Но это еще не все — с помощью аналогичных функций можно проверять символы на целый ряд других качеств. Функции, которые предназначены для проверки характеристик символов, приведены в табл. 4.3. Для широких символов используйте функции с такими же именами, но с буквой «w» после «is», например iswSpace
. Версии для широких символов объявлены в заголовочном файле <cwctype>
.
Функция | Описание |
---|---|
isalpha iswalpha | Буквенные символы: a-z, A-Z (верхний или нижний регистр) |
isupper iswupper | Буквенные символы верхнего регистра: A-Z |
islower iswlower | Буквенные символы нижнего регистра: a-z |
isdigit iswdigit | Числовые символы: 0-9 |
isxdigit iswxdigit | Шестнадцатеричные числовые символы: 0-9, a-f, A-F |
isspace iswspace | Пробельные символы. ' ', , , v, , l |
iscntrl iswcntrl | Управляющие символы: ASCII 0-31 и 127 |
ispunct iswpunct | Символы пунктуации, не принадлежащие предыдущим группам |
isalnum iswalnum | isalpha или isdigit равны true |
isprint iswprint | Печатаемые символы ASCII |
isgraph iswgraph | isalpha , isdigit или ispunct равны true |
После того как были прочтены все символы и достигнут конец файла, требуется сделать еще кое-что. Во-первых, строго говоря, цикл подсчитывает только переносы строк, а не сами строки. Следовательно, это значение будет на одну меньше, чем реальное число строк. Чтобы решить эту проблему, я, если файл содержит ненулевое число символов, просто увеличиваю счетчик строк на единицу. Во-вторых, если поток заканчивается на буквенно-цифровой символ, то поиск конца последнего слова не сработает, так как не будет следующего символа. Чтобы учесть это, я проверяю, является ли последний символ потока буквенно-цифровым (также только в том случае, если в файле содержится ненулевое число символов), и увеличиваю счетчик слов на единицу.
Методика использования потоков в примере 4.26 почти идентична той, которая описана в рецептах 4.14 и 4.15, но несколько проще, так как он только исследует файл, не внося никаких изменений.
Рецепты 4.14 и 4.15.
4.18. Подсчет вхождений каждого слова в текстовом файле
Требуется подсчитать количество вхождений в текстовом файле каждого слова.
Для чтения из текстового файла непрерывных фрагментов текста используйте operator>>
, определенный в <string>
, а для сохранения каждого слова и его частоты в файле используйте map
, определенный в <map>
. Пример 4.27 демонстрирует, как это делается.
1 #include <iostream>
2 #include <fstream>
3 #include <map>
4 #include <string>
5
6 typedef std::map<std::string, int> StrIntMap;
7
8 void countWords(std::istream& in, StrIntMap& words) {
9
10 std::string s;
11
12 while (in >> s) {
13 ++words[s];