программа с использованием string.h 'strtok': This function or variable may be unsafe. Consider using strtok_s instead

Было такое задание. Ввести предложение длиной не более 80 символов. Вывести слова, которые заканчиваются на ту же букву, что и первое слово, и их количество. Количество пробелов между словами произвольно. И код надо было написать с помощью string.h. Я все уже перепробовал. В финальном коде который я прикрепил сюда, вылетает такая ошибка, как я ему могу решить? Буду очень благодарен за помощь.

#include <iostream>
#include <locale>
#include <Windows.h>
#include <string.h>

int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    using namespace std;
    const int MAX_LENGTH = 80;

    char sentence[MAX_LENGTH];
    cout << "Введите предложение (не более 80 символов):\n";
    cin.getline(sentence, MAX_LENGTH);

    int firstWordEnd = 0;
    while (sentence[firstWordEnd] != ' ' && sentence[firstWordEnd] != '\0')
    {
        firstWordEnd++;
    }

    char lastLetter = sentence[firstWordEnd - 1];
    cout << "Слова, которые заканчиваются на ту же букву, что и первое слово:\n";
    int wordCount = 0;
    int spaceCount = 0;
    bool isFirstWord = true;

    char* token = strtok(sentence, " ");
    while (token != NULL)
    {
        if (isFirstWord) {
            isFirstWord = false;
            token = strtok(NULL, " "); // Пропускаем первое слово
            continue;
        }

        if (token[strlen(token) - 1] == lastLetter) {
            cout << token << endl;
            wordCount++;
        }

        token = strtok(NULL, " ");
    }

    cout << "Количество слов, заканчивающихся на ту же букву, что и первое слово: " << wordCount << endl;

    return 0;
}

Фото ошибкивведите сюда описание изображения


Ответы (1 шт):

Автор решения: NunOfIt

Просто добавьте #define _CRT_SECURE_NO_WARNINGS и не мучайтесь, у вас тут проблема в другом.

При вводе символов русского алфавита они занимают не один байт памяти, а два. Т.е. вам нужно зарезервировать не массив на 80 char-ов, а на 161 (80 символов р.а. и один символ конца строки), но тут ещё прикол в том, что пробела весят не два байта а один, так же как и символы русского алфавита, т.е. теоретически можно будет ввести более чем 80 символов...

Вам не нужно искать последниё символ первого слова в цикле, вы в строке char* token = strtok(sentence, " "); это последнее слово в token записываете, оттуда и нужно вытаскивать последний символ. и перед входом в цикл записать token = strtok(nullptr, " ");, таким образом переменная isFirstWord и всё, что с ней связано становятся совершенно ненужными.

И как я уже скзал символы р.а. записываются в двух байтах и в этой строке token[strlen(token) - 1] == lastLetter вы по сути сравниваете только один из них.

#define _CRT_SECURE_NO_WARNINGS

#include <locale>
#include <iostream>
#include <string.h>

int main()
{
    setlocale(LC_ALL, "");
    const int MAX_LENGTH = 161;
    char sentence[MAX_LENGTH]{};

    // Лямбда-функция, которая выдаёт последний элемент строки
    auto get_ll = [](char* str) -> char* {
        char* res = str + strlen(str) - 1;

        // для английского алфавита
        if(*res >= 'a' && *res <= 'z' || *res >= 'A' && *res <= 'Z')
            return res;

        // для русского алфавита
        return --res;
    };

    std::cout << "Введите предложение: ";
    std::cin.getline(sentence, MAX_LENGTH - 1);
    
    int wordCount = 0;
    char* token = strtok(sentence, " ");
    char* lastLetter = get_ll(token);
    std::cout << "Первое слово (ПС): " << token << '\n';
    std::cout << "Последняя буква ПС: " << lastLetter << '\n';

    std::cout << "Искомые слова: ";
    token = strtok(nullptr, " ");
    while (token) {
        if (!strcmp(get_ll(token), lastLetter)) {
            std::cout << token << ' ';
            ++wordCount;
        }
        token = strtok(nullptr, " ");
    }
    std::cout << "\nКоличество искомых слов: " << wordCount << '\n';
    return 0;
}

Несколько тестов:

введите сюда описание изображения

введите сюда описание изображения

введите сюда описание изображения

→ Ссылка