программа с использованием 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 шт):
Просто добавьте #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;
}
Несколько тестов:



