С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/3: Рейтинг темы: голосов - 3, средняя оценка - 5.00
 Аватар для NightRain
0 / 0 / 0
Регистрация: 01.02.2013
Сообщений: 103

Подсчет слов в предложениях

17.06.2017, 12:36. Показов 740. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте! При написании исходника столкнулся с проблемой подсчета слов. Где может быть ошибка? В принципе задача: Из файла считать предложения и указать сколько раз повторяется введенное пользователем слово в предложении

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <fstream>
#include <iostream>
#include <cstring>
using namespace std;
int main() {
    setlocale(LC_ALL, "Russian");
    const int len = 281;
    char word[len], line[len];
    char delims[] = ".!?";
    cout << "Введите слово для поиска: "; cin >> word;
    int l_word = strlen(word);
    ifstream fin("text.txt");
    if (!fin) { cout << "Ошибка открытия файла." << endl; return 1; }
    int count = 0;
    while (fin.getline(line, len)) {
        char *token = strtok(line, delims); // 1
        while (token != NULL) {
            count = 0;
            char *p = token;
            while (strstr(p, word)) {
                char *c = p;
                p += l_word;
                if (c != line) // слово не в начале строки? //////// 4
                               // символ перед словом не разделитель?
                    if (!ispunct(*(c - 1)) && !isspace(*(c - 1))) //////// 4
                        continue; //////// 4
                                  // символ после слова разделитель?
                if (ispunct(*p) || isspace(*p) || (*p == '\0'))
                count++;
            }
             // 2
            cout << token << "(" << count << ")" << endl;
            
            token = strtok(NULL, delims); // 3
            
        }
        
        
        
    }
    system("pause");
    return 0;
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
17.06.2017, 12:36
Ответы с готовыми решениями:

Файлы: подсчет количества слов в предложениях
Написать программу на С++, которая посчитает количество слов в предложениях. • входными данными является файл; • результаты работы...

Работа со строками. Подсчет количества слов в предложениях и т.д
С клавиатуры вводится текстовая строка. Составить программу которая: 1) считает количество слов в каждом предложении; 2) выводит на...

Определение среднего количества слов в предложениях
При написании программных продуктов, обрабатывающих различные тексты, часто появляется необходимость исследовать некоторые статистические...

14
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
17.06.2017, 14:15
А для чего strstr()? После strtok() сразу слова должны получаться. Пробел добавь в delims.
0
 Аватар для NightRain
0 / 0 / 0
Регистрация: 01.02.2013
Сообщений: 103
17.06.2017, 17:11  [ТС]
Должны, но считает он не верно. Например несколько слов в предложении не видит. И пробел не нужен, тогда он будет делить на слова, а не на предложения
0
23 / 23 / 6
Регистрация: 23.03.2013
Сообщений: 245
17.06.2017, 17:27
Скорее всего по названию и содержанию темы подумали что нужно подсчитать количество слов )))
0
 Аватар для NightRain
0 / 0 / 0
Регистрация: 01.02.2013
Сообщений: 103
17.06.2017, 18:08  [ТС]
Причем счет действительно странный
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
17.06.2017, 19:08
Тогда используй strtok() ещё раз, чтобы предложение разделить на слова.
0
 Аватар для NightRain
0 / 0 / 0
Регистрация: 01.02.2013
Сообщений: 103
18.06.2017, 09:31  [ТС]
Типа этого? Я иду на правильном пути? Где-то я явно ошибаюсь
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <fstream>
#include <iostream>
#include <cstring>
using namespace std;
int main() {
    setlocale(LC_ALL, "Russian");
    const int len = 281;
    char word[len], line[len];
    char delims[] = ".!?";
    cout << "¬ведите слово дл¤ поиска: "; cin >> word;
    int l_word = strlen(word);
    ifstream fin("text.txt");
    if (!fin) { cout << "ќшибка открыти¤ файла." << endl; return 1; }
    int count = 0;
    while (fin.getline(line, len)) {
        
        char *token = strtok(line, delims); // 1
        
        while (token != NULL) {
            count = 0;
            char *slovo = strtok(line, word);
            while (slovo != NULL) {
            char *p = slovo;
            
                p += l_word;
                //  if (c = token)
                count++;
                
            }
            slovo = strtok(NULL, word);
        }
            count = 0;
            cout << token << "(" << word << ")" << endl;
            token = strtok(NULL, delims);
            
 
        }
    system("pause");
    return 0;
}
Добавлено через 2 часа 7 минут
Решил сам. Кто столкнется, вот ответ:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <fstream>
#include <iostream>
#include <cstring>
using namespace std;
int main() {
    setlocale(LC_ALL, "Russian");
    const int len = 281;
    char word[len], line[len];
    char delims[] = ".!?";
    cout << "¬ведите слово дл§ поиска: "; cin >> word;
    int l_word = strlen(word);
    ifstream fin("text.txt");
    if (!fin) { cout << "ќшибка открыти¤ файла." << endl; return 1; }
    int count = 0;
    while (fin.getline(line, len)) {
        char *token = strtok(line, delims); // ищем пунктуацию и делим на предл-и¤
        while (token != NULL) {
            count = 0;
            char *p = token; //указатель на массив
            while ((p = strstr(p, word)) != NULL) {  //ищем слово в предложении
                p++; //увеличиваем строку
                count++; //увеличиваем счетчик
            }
 
            cout << token << "(" << count << ")" << endl;
            token = strtok(NULL, delims);
        }
    }
    system("pause");
    return 0;
}
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
18.06.2017, 09:49
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    char word[len], line[len], w[len];
 
    //...
 
    while (fin.getline(line, len))
    {
        char *token = strtok(line, delims);
        
        while (token != NULL)
        {
            count = 0;
            std::istringstream iss(token);
            while (iss >> w)
                if (strcmp(word, w) == 0) ++count;
 
            //...
 
            token = strtok(NULL, delims);
        }
     }
1
23 / 23 / 6
Регистрация: 23.03.2013
Сообщений: 245
18.06.2017, 11:11
Цитата Сообщение от nmcf Посмотреть сообщение
C++
1
2
std::istringstream iss(token);
while (iss >> w)
Это только на пробелы ведь работает?!

Если после слова(или перед) сразу будет какой-нибудь знак, то его тоже вместе со словом захватит .

Например "Hello, world" , будет 2 слова, "Hello," и "world". (или "Hello ,world" -> "Hello" и ",world")
0
 Аватар для Nishen
1357 / 856 / 365
Регистрация: 26.02.2015
Сообщений: 3,813
18.06.2017, 11:20
karaulov6, в общем случае можно сначала по пробелам выделить слова. Потом удалять с начала и с конца полученных строк знаки пунктуации, если это необходимо.
0
23 / 23 / 6
Регистрация: 23.03.2013
Сообщений: 245
18.06.2017, 12:17
Мне то это не важно, а вдруг ТС'у нужно что бы работало как положено ?

В его варианте кажется поиск по "подстроке" а не по словам, а вариант nmcf, только с пробелами работает

Добавлено через 14 минут
Может так? Вроде бы работает, по крайней мере с английскими буквами.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
 
using namespace std;
 
 
vector<string> GetSentsFromLine( string line, string delims )
{
    vector<string> out;
    ostringstream buffer;
    int currentchar = 0;
    while ( line.length() > currentchar )
    {
        bool foundendsent = false;
        for ( char c : delims )
        {
            if ( line[ currentchar ] == c )
            {
                foundendsent = true;
            }
        }
 
        if ( foundendsent && buffer.str( ).length( ))
        {
            out.push_back( buffer.str( ) );
            buffer.str( "" );
            buffer.clear( );
        }
        else
            buffer << line[ currentchar ];
        currentchar++;
    }
 
    if ( buffer.str( ).length( ) )
        out.push_back( buffer.str( ) );
    return out;
}
 
 
vector<string> GetWordsFromLine( string line )
{
    vector<string> out;
    ostringstream buffer;
    int currentchar = 0;
    bool buildword = false;
    while ( line.length( ) > currentchar )
    {
        buildword = isalpha( line[ currentchar ] );
 
        while ( line.length( ) > currentchar && buildword )
        {
            buffer << line[ currentchar ];
            currentchar++;
            buildword = isalpha( line[ currentchar ] );
        }
 
        if ( buffer.str( ).length( ) && buffer.str( ).length( ) )
        {
            out.push_back( buffer.str( ) );
            buffer.str( "" );
            buffer.clear( );
        }
 
        currentchar++;
    }
 
    if ( buffer.str( ).length( ) )
        out.push_back( buffer.str( ) );
 
    return out;
}
 
 
 
int main( )
{
    setlocale( LC_ALL, "Russian" );
    string inword, line, wordbuffer;
 
    char * SentDelims = ".!?";
 
 
    cout << "Введите слово для поиска: ";
    std::getline( cin, inword ); // чтение целой строки в word
    ifstream fin( "text.txt" );
    if ( !fin.is_open( ) )
    {
        cout << "Ошибка открытия файла." << endl;
        return 1;
    }
 
    int count = 0;
    while ( getline( fin, line ) ) // чтение построчно из файла
    {
        vector<string> ListOfSent = GetSentsFromLine( line,SentDelims );
        for ( string sent : ListOfSent )
        {
            int wordcount = 0;
            vector<string> ListOfWord = GetWordsFromLine( sent );
 
            for ( string word : ListOfWord )
            {
                if ( word == inword )
                    wordcount++;
            }
 
            cout << sent << "(" << wordcount << ")" << endl;
        }
    }
 
    ::system( "pause" );
    return 0;
}
1
18.06.2017, 12:20

Не по теме:

Да он уже сделал по-своему.

0
23 / 23 / 6
Регистрация: 23.03.2013
Сообщений: 245
18.06.2017, 12:28

Не по теме:

Если я правильно понял у него не ищет слова, а подстроки



И вообще если учат C++ языку, то зачем использовать 'char' массивы если есть std::string ?

Вместо: (какой-то "гибрид" 'C' и 'C++' )
C++
1
2
char buffer[256];
infile.getline(buffer,256);
В 'C++' это выглядит так:

C++
1
2
string buffer;
getline(infile,buffer);
1
 Аватар для NightRain
0 / 0 / 0
Регистрация: 01.02.2013
Сообщений: 103
18.06.2017, 18:29  [ТС]
И вообще если учат C++ языку, то зачем использовать 'char' массивы если есть std::string ?
Затем что это практикум Павловской
Я понимаю что так проще
0
23 / 23 / 6
Регистрация: 23.03.2013
Сообщений: 245
18.06.2017, 20:38
так если строка в файле будет больше размера буфера, то код будет работать не правильно.

А в C++ , никакого размера буфера не нужно указывать, все само делает )))


Ну я к тому что C++ по идее должен быть удобнее чем просто 'C'
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
18.06.2017, 20:38
Помогаю со студенческими работами здесь

Строки. Поиск одинаковых слов в предложениях. Вывод вместо одинаковых слов "*"
Ввести два предложения, если в них есть одинаковые слова то во втором предложении заменить эти слова на &quot;*&quot;, причем количество...

Подсчёт слов в строке. Подсчёт символов в словах строки
Начал изучение строк в С++. Решая задачу по поиску количества строк и количеству указанных символов упёрся лбом в стену. Теорию понял:...

Ввод слов в массив и подсчёт введённых слов
как можно решить эту задачу:Напишите программу,использующую массив char и цикл для чтения по одному слову за раз до тех пор,пока не будет...

Поменять порядок слов в предложениях на обратный
У меня вот такая проблема- программа которая меняет порядок слов в предложениях на обратный из данного файла допустим а.txt в котором 2-3...

Подсчитать среднее количество слов в предложениях
Написать программу, анализирующую заданный текстовый файл: 2) подсчитать среднее количество слов в предложениях Предусмотреть обработку...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru