Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/41: Рейтинг темы: голосов - 41, средняя оценка - 4.63
1 / 1 / 0
Регистрация: 25.07.2019
Сообщений: 42

Как сделать проверку на наличие недопустимого слова?

29.07.2019, 13:03. Показов 7700. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Как сделать следующее:

Строка: hello world test

На выходе: Ошибка, потому что слово test не предусмотрено.

Мне нужно сделать ограничение, т.е. есть допустимые слова (например hello и world) и, если в строке найдено слово, которое не входит в список этих слов, написать Ошибка
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
29.07.2019, 13:03
Ответы с готовыми решениями:

Как сделать проверку наличие листа?
Нужна помощь в написании формулы, смысл такой: листы в книге пронумерованы 1,2,3,4...31 (дни месяца), они добавляются, в эту книгу...

Как сделать проверку в таблице на наличие данных?
Здоровья уважаемые! Собственно столкнулся с маааленькой и слегка неудобной проблемкой. Итак дано 2 таблицы которые суммируются,...

Как сделать проверку на наличие пользователя по паролю?
И так, доброго времени суток. У нас есть список пользователей, в задании сказано, удалить одного из пользователей по заданному паролю с...

14
260 / 165 / 54
Регистрация: 03.05.2019
Сообщений: 339
29.07.2019, 13:15
С использованием потока:
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
#include <iostream>
#include <string>
#include <sstream>
#include <Windows.h>
using namespace std;
 
string To_Low(string text) // - преобразование в нижний регистр
{
    for (unsigned int i = 0; i < text.length(); i++)
        if (isupper((unsigned char)text[i]))
            text[i] = tolower(text[i]);
    return text; // - возвращает преобразованную копию строки
}
 
int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
 
    string text, word;
    cout << "Введите текст: ";
    getline(cin, text);
    cout << "Введите недопустимое слово: ";
    getline(cin, word);
 
    istringstream flow(text); // - формируем поток с текста (данные записаны в поток)
    bool error = false;
    text.clear(); // - теперь текст будет в роли буфера для проверки слов
    while (flow >> text)
        if (text == word || To_Low(text) == To_Low(word)) // - проверка, не зависящая от регистра
            error = true;
 
    if (error)
        cout << "Ошибка, потому что слово \"" << word << "\" не предусмотрено.\n";
    else
        cout << "Текст допустимен.\n";
 
    return 0;
}
Есть функция преобразование в нижний регистр, чтобы при "hello my TeXt" и недопустимом слове "text" выдавало ошибку, если вам это не нужно, функция не надо.
1
1 / 1 / 0
Регистрация: 25.07.2019
Сообщений: 42
29.07.2019, 13:29  [ТС]
Спасибо но это не то, у меня есть список допустимых слов и вот если в этой строке есть слово которого нет в этом списке
написать 'Ошибка'.
Кстати на счёт регистров спасибо, я об этом не подумал.
0
 Аватар для SomniPhobia
602 / 439 / 137
Регистрация: 22.11.2017
Сообщений: 1,408
29.07.2019, 13:33
Лучший ответ Сообщение было отмечено daneil9 как решение

Решение

daneil9, привет!
Цитата Сообщение от daneil9 Посмотреть сообщение
есть допустимые слова (например hello и world) и, если в строке найдено слово, которое не входит в список этих слов, написать Ошибка
С использованием функции split_mod().
Кликните здесь для просмотра всего текста

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
#include <iostream>
#include <string>
#include <fstream>
#include <set>
#include <list>
#include <algorithm>
 
template<typename InIt, typename OutIt>
void split_mod
(
    InIt it_begin_s,
    InIt it_end_s,
    InIt it_begin_seps,
    InIt it_end_seps,
    OutIt it_out
);
 
int main()
{
    std::wcout.imbue(std::locale("rus_rus.866"));
    std::wcin.imbue(std::locale("rus_rus.866"));
    std::wstring seps(L" .,?!/\\\"|'~`@#№$;:%^*(){}[]<>-—+");
 
    //Белый список
    std::set<std::wstring> allowed_words{ L"hello", L"world" };
 
    std::wcout << L"Введите строку\n";
    std::wstring line;
    std::getline(std::wcin, line);
    std::list<std::wstring> words_in_line;
    split_mod(std::begin(line), std::end(line), std::begin(seps), std::end(seps), std::back_inserter(words_in_line));
    bool flag = true;
    setlocale(LC_CTYPE, "Rus");
    for (auto& word : words_in_line)
    {
        std::wstring word_down;
        std::transform(std::begin(word), std::end(word), std::back_inserter(word_down), ::towlower);
        if (!allowed_words.count(word_down))
        {
            setlocale(LC_CTYPE, "C");
            std::wcout << L"Ошибка. Слово \"" << word_down << L"\" не предусмотрено\n";
            flag = false;
            break;
        }
    }
    setlocale(LC_CTYPE, "C");
    std::wcout << (flag ? L"Текст содержит только допустимые слова\n" : L"");
 
    return 0;
}
 
template<typename InIt, typename OutIt>
void split_mod
(
    InIt it_begin_s,
    InIt it_end_s,
    InIt it_begin_seps,
    InIt it_end_seps,
    OutIt it_out
)
{
    if (!is_sorted(it_begin_seps, it_end_seps))
        sort(it_begin_seps, it_end_seps);
    using S = typename std::basic_string<std::iterator_traits<InIt>::value_type>;
    InIt it_old = it_begin_s;
    for (InIt it = it_begin_s; it != it_end_s; ++it)
        if (std::binary_search(it_begin_seps, it_end_seps, *it))
        {
            if (it_old != it)
                * it_out++ = S(it_old, it);
            it_old = it;
            std::advance(it_old, 1u);
        }
    if (it_old != it_end_s)
        * it_out++ = S(it_old, it_end_s);
}
Миниатюры
Как сделать проверку на наличие недопустимого слова?   Как сделать проверку на наличие недопустимого слова?  
2
1 / 1 / 0
Регистрация: 25.07.2019
Сообщений: 42
29.07.2019, 13:59  [ТС]
Привет, а для какого компилятора этот код( просто у меня gcc ругается на этот код )
0
 Аватар для SomniPhobia
602 / 439 / 137
Регистрация: 22.11.2017
Сообщений: 1,408
29.07.2019, 14:12
daneil9, я писал в Microsoft Visual Studio Community 2019.
На что именно ругается?
0
1 / 1 / 0
Регистрация: 25.07.2019
Сообщений: 42
29.07.2019, 14:31  [ТС]
На
std::wstring seps(L" .,?!/\\"|'~`@#¹$;:%^*(){}[]<>-—+");
[Error] converting to execution character set: Illegal byte sequence

std::set<std::wstring> allowed_words{ L"hello", L"world" };
[Error] in C++98 'allowed_words' must be initialized by constructor, not by '{...}'

split_mod(std::begin(line), std::end(line), std::begin(seps), std::end(seps), std::back_inserter(words_in_line));
[Error] 'begin' is not a member of 'std'

...
0
1741 / 913 / 480
Регистрация: 05.12.2013
Сообщений: 3,074
29.07.2019, 15:09
daneil9, если используется CodeBlock, то он компилирует по умолчанию по стандарту с++98 и для файлов использует кодировку win-1251, нужно в build options поставить галку на стандарте с++14 и кодировку файлов поменять
1
1 / 1 / 0
Регистрация: 25.07.2019
Сообщений: 42
29.07.2019, 15:30  [ТС]
Спасибо всё получилось))

Добавлено через 10 минут
Кстати вопрос не по теме может ли программа крашеться из за чрезмерного использования include файлов cpp
И вообще как мне новичку оптимизировать код (в частности памяти)
0
260 / 165 / 54
Регистрация: 03.05.2019
Сообщений: 339
29.07.2019, 15:34
Лучший ответ Сообщение было отмечено daneil9 как решение

Решение

Цитата Сообщение от daneil9 Посмотреть сообщение
Спасибо но это не то, у меня есть список допустимых слов и вот если в этой строке есть слово которого нет в этом списке
Можно тоже реализовать через потоки:
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
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <Windows.h>
using namespace std;
 
string To_Low(string text) // - преобразование в нижний регистр
{
    for (unsigned int i = 0; i < text.length(); i++)
        if (isupper((unsigned char)text[i]))
            text[i] = tolower(text[i]);
    return text; // - возвращает преобразованную копию строки
}
 
void Filling(vector<string>& words) // - заполнение вектора слов
{
    string line;
    cout << "Через пробел введите допустимые слова: ";
    getline(cin, line);
 
    istringstream flow(line);
    line.clear();
    while (flow >> line)
        words.push_back(line);
 
    /* Можно заполнять и другим способом:
    cout << "Слова (для завершение введите 0): ";
    while (line != "0")
        words.push_back(line);*/
}
 
int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
 
    string text;
    cout << "Введите текст: ";
    getline(cin, text);
    vector<string> words; // - вектор допустимых слов
    Filling(words);
 
    istringstream flow(text); // - формируем поток с текста (данные записаны в поток)
    bool error = true;
    text.clear(); // - теперь текст будет в роли буфера для проверки слов
    while (flow >> text)
    {
        error = true;
        for (unsigned int i = 0; i < words.size(); i++)
        {
            if (text == words[i] || To_Low(text) == To_Low(words[i]))
                error = false;
        }
    }
 
    if (error)
        cout << "Ошибка.\n";
    else
        cout << "Текст допустимен.\n";
 
    return 0;
}
Цитата Сообщение от daneil9 Посмотреть сообщение
Кстати на счёт регистров спасибо, я об этом не подумал.
Пожалуйста.
3
 Аватар для SomniPhobia
602 / 439 / 137
Регистрация: 22.11.2017
Сообщений: 1,408
30.07.2019, 09:21
daneil9, ТабуретY верно заметил про кодировку. Тут вся работа с кодировками + широкие строки задействованы, чтобы иметь возможность обрабатывать кириллицу (русские символы в строках).
Я перевёл всё в более новую кодировку 1251.
Список разрешённых слов лучше хранить и брать из файла (например, allowed_words.txt). Он обязательно должен быть в 1251 кодировке (смотри стрелки на скрине). Из файла удобней брать чем вшивать в код или каждый раз запрашивать у пользователя.
daneil9, тебя попрошу объяснить для чего в моём коде нужна каждая из строк с 28 по 32 включительно - включительно соответственно.
Да, забыл сказать, для работы этого кода включи не C++14, а C++17 в настройках.

Кликните здесь для просмотра всего текста

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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <iostream>
#include <fstream>
#include <windows.h>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <optional>
 
std::vector<std::wstring> read_allowed_words_from_file(const std::wstring& path, std::wstring& seps);
 
std::optional<std::wstring> check_line(const std::vector<std::wstring>& allowed_words, std::wstring& line, std::wstring& seps);
 
template<typename InIt, typename OutIt>
void split_mod
(
    InIt it_begin_s,
    InIt it_end_s,
    InIt it_begin_seps,
    InIt it_end_seps,
    OutIt it_out
);
 
void wstring_towlower(std::wstring& str);
 
int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    setlocale(LC_CTYPE, ".1251");
    std::wcout.imbue(std::locale("rus_rus.1251"));
    std::wcin.imbue(std::locale("rus_rus.1251"));
    std::wstring seps(L" .,?!/\\\"|'~`@#№$;:%^*(){}[]<>-—+\t");
    const std::wstring path(L"allowed_words.txt");
 
    /*
    //Создание файла *.txt в кодировке 1251, если такового не имеется
    std::wofstream wfout(path);
    wfout.imbue(std::locale("rus_rus.1251"));
    wfout << L"Заполитель\n";
    wfout.close();
    */
 
    //Белый список
    std::vector<std::wstring> allowed_words;
    try
    {
        allowed_words = read_allowed_words_from_file(path, seps);
    }
    catch (const wchar_t *err)
    {
        std::wcout << err << L"\n";
        return 1;
    }
    
    std::wcout << L"Введите строку\n";
    std::wstring line;
    std::getline(std::wcin, line);
    auto res = check_line(allowed_words, line, seps);
    std::wcout <<
        (!res ?
            L"Текст содержит только допустимые слова\n" :
            L"Ошибка. Слово \"" + *res + L"\" не предусмотрено\n")
        << L"\n";
 
    return 0;
}
 
std::vector<std::wstring> read_allowed_words_from_file(const std::wstring& path, std::wstring& seps)
{
    //Белый список
    std::vector<std::wstring> allowed_words;
    std::wifstream wfin;
    wfin.imbue(std::locale("rus_rus.1251"));
    wfin.open(path);
    if (!wfin.is_open())
    {
        throw L"Ошибка. Файл не удалось открыть\n";
    }
    std::wstring dump;
    for (; wfin.good();)
    {
        std::wstring line;
        std::getline(wfin, line);
        if (!line.empty())
        {
            dump += line + seps.front();
        }
    }
    wfin.close();
    split_mod(std::begin(dump), std::end(dump), std::begin(seps), std::end(seps), std::back_inserter(allowed_words));
    for (auto& word : allowed_words)
    {
        wstring_towlower(word);
    }
    std::sort(std::begin(allowed_words), std::end(allowed_words));
    auto new_end = std::unique(std::begin(allowed_words), std::end(allowed_words));
    allowed_words.erase(new_end, std::end(allowed_words));
    return allowed_words;
}
 
std::optional<std::wstring> check_line(const std::vector<std::wstring>& allowed_words, std::wstring& line, std::wstring& seps)
{
    std::list<std::wstring> words_in_line;
    split_mod(std::begin(line), std::end(line), std::begin(seps), std::end(seps), std::back_inserter(words_in_line));
    bool flag = true;
    for (auto& word : words_in_line)
    {
        wstring_towlower(word);
        if (!std::binary_search(std::begin(allowed_words), std::end(allowed_words), word))
        {
            return word;
        }
    }
    return {};
}
 
template<typename InIt, typename OutIt>
void split_mod
(
    InIt it_begin_s,
    InIt it_end_s,
    InIt it_begin_seps,
    InIt it_end_seps,
    OutIt it_out
)
{
    if (!is_sorted(it_begin_seps, it_end_seps))
        sort(it_begin_seps, it_end_seps);
    using S = typename std::basic_string<std::iterator_traits<InIt>::value_type>;
    InIt it_old = it_begin_s;
    for (InIt it = it_begin_s; it != it_end_s; ++it)
        if (std::binary_search(it_begin_seps, it_end_seps, *it))
        {
            if (it_old != it)
                * it_out++ = S(it_old, it);
            it_old = it;
            std::advance(it_old, 1u);
        }
    if (it_old != it_end_s)
        * it_out++ = S(it_old, it_end_s);
}
 
void wstring_towlower(std::wstring& str)
{
    for (auto& c : str)
    {
        c = towlower(c);
    }
}
Миниатюры
Как сделать проверку на наличие недопустимого слова?   Как сделать проверку на наличие недопустимого слова?  
1
1 / 1 / 0
Регистрация: 25.07.2019
Сообщений: 42
30.07.2019, 13:26  [ТС]
@amator_C, Спасибо ещё раз и у меня к вам вопрос. Можно ли сделать так что-бы слова в кавычках не проверялись
при этом была возможность на экранирование кавычек - ("...бэкслэш"...")
0
 Аватар для SomniPhobia
602 / 439 / 137
Регистрация: 22.11.2017
Сообщений: 1,408
30.07.2019, 13:32
daneil9, можно хоть что сделать. Было бы:
а) желание;
б) время;
в) знания и опыт.
1
1 / 1 / 0
Регистрация: 25.07.2019
Сообщений: 42
30.07.2019, 13:36  [ТС]
SomniPhobia, желание и время есть ,а вот знаний и опыта маловата для этой задачи (я про себя)
0
 Аватар для SomniPhobia
602 / 439 / 137
Регистрация: 22.11.2017
Сообщений: 1,408
30.07.2019, 14:44
daneil9, у классов string, wstring есть нестатические методы front(), back(), которые возвращают первый и последний символ для строки от экземпляра которой вызываются. После расщепления исходной строки на слова, для каждого из слов вызови front(), back() и посмотри, если это кавычки, то обыграй эту ситуацию как исключение.
Для расщепителя, в моём коде, нужно убрать символ " из контейнера seps.
Пробуй сам коды писать. По - началу тяжело. Потом, с опытом, становится легко и интересно.

Добавлено через 4 минуты
Сделай проверку чтобы символов " в исходной строке было чётное количество. Рекомендую через count_if(итератор на начало строки, итератор на конец строки, символ подсчёта). count_if() возвращает количество вхождений элемента подсчёта в контейнер.

Добавлено через 13 минут
Нужно отлавливать ситуации вроде следующих
при"вет как дел"а
По сути кавычки две - чётное, но они расставлены не корректно. Как это отловить?
Я предлагаю для каждого слова
значение, возвращённое функцией count_if(начало слова, конец слова, кавычка)
если равно двум, тогда смотрим края через front(), back(). Если на краях стоят по кавычке - всё норм для этого слова.
если равно нулю - сразу всё норм.
если это не ноль и не два, то ошибка.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
30.07.2019, 14:44
Помогаю со студенческими работами здесь

Как сделать проверку базы адресов на наличие мертвых ссылок?
Как сделать проверку базы адресов на наличие мертвых ссылок?

Как сделать проверку на наличие свойства и только потом вывести значение ?
Здравствуйте! На странице разместил bitrix:news.line подключил несколько инфоблоков, подключены как просто инфоблок новости с картинкой так...

Сделать проверку на наличие цифр в Edit
Здравствуйте мне нужна ваша помощь. У меня есть Edit и Memo. Нужно вывести цифры в Edit и вывести в Memo. Это я сделал, но есть одно но,...

Как сделать проверку на вхождение слова в RichTextBox
нужно для создания компилятора... например: Если отсутствует START(); , то программа пишет ошибку, а если есть, то компилирует, и если...

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


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru