• 🔥 Бесплатный курс от Академии Кодебай: «Анализ защищенности веб-приложений»

    🛡 Научитесь находить и использовать уязвимости веб-приложений.
    🧠 Изучите SQLi, XSS, CSRF, IDOR и другие типовые атаки на практике.
    🧪 Погрузитесь в реальные лаборатории и взломайте свой первый сайт!
    🚀 Подходит новичкам — никаких сложных предварительных знаний не требуется.

    Доступ открыт прямо сейчас Записаться бесплатно

Поиск в тексте символов (c++)

  • Автор темы Автор темы o1ps
  • Дата начала Дата начала
Статус
Закрыто для дальнейших ответов.
O

o1ps

Возникла задача : Задан текст, состоящий из слов, записанных через запятые, и заканчивающийся точкой.
Длина текста не больше 150 символов, могут быть использованы любые символы. Словом
считается после-довательность символов, не содержащая пробел. Сформировать строку из
5-символьных слов, несо-держащих букву s. Получить массив кубов цифровых слов.


Вот код, который мне удалось реализовать:
Код:
//#include "stdafx.h"
#include <stdlib.h>
// для функции exit()

#include <string.h>
#include <iostream.h>
#include <cstdio>
// для функций работы с файлами

void main(void) {
char
text[149],	// загруженный из файла текст

*_word,	// рабочая переменная для корректного
// разделения строки на слова

**words,	// здесь будут храниться все слова из строки

fourSW[150], // в этом массиве будут храниться слова длиной в 4
// символа, содержащие буквы и цифры

**repeatWord;
// этот массив будет содержать повторяющиеся слова

words = new char*[150];
repeatWord = new char*[150];

int
i,	//
j,	// счётчики циклов
k,	//

word=0,		// количество слов в загруженной строке

lengths[150],		// длины каждого слова

digitPos=0,		// рабочая переменная, которая будет содержать
// информацию о словах содержащих цифры

repeat[150],		// количество повторений для каждого слова

squares[150][3],	// кубы цифровых слов

sq=0,			// количество цифровых слов

repeats=0;		// общее количество различных слов в тексте

FILE *fp;	// указатель на дескриптор файла

/* Нижеследующие переменные созданы для показа умения работы со строковыми функциями */
char text1[9]="Proverka";
char text2[10]="Propil'on";
char *p;

if ((fp = fopen("data.txt", "r")) == NULL) goto fileNotExists;
// открываем файл, если не удаётся - уходим в ошибку

fread(&text, sizeof(char), 150, fp);
cout << "Loaded text: " << text << endl << endl;
fclose(fp);
// читаем из файла 150 символов, выводим текст, закрываем файл

/* следующий блок делит считанную строку на массив слов, с которым
гораздо удобнее работать */
do {
if (word==0) {
_word = strtok(text, ",");
} else {
_word = strtok(NULL, ",");
}	// для определения каждого последующего слова используется
// функция strtok()

if (_word == NULL) break;

word++;
words[word] = new char[strlen(_word)];
words[word] = _word;
lengths[word] = strlen(_word);
// заносим слово в массив words[], а его длину - в lengths[]
} while (1);

cout << endl << "Words (length = 5) with digits and characters:" << endl;

strcpy(fourSW, "");
/* следующий блок кода найдёт все слова, содержащие и буквы и цифры,
и не имеющие при себе буквы s */
for (i=1; i<=word; i++) {
digitPos=strcspn(words[i], "s");
// ищем, на какой позиции встречается буква в слове
if (atoi(words[i])==0 && digitPos>0 && digitPos!=lengths[i] && lengths[i]==4) {
strcat(fourSW, words[i]);
strcat(fourSW, ", ");
}
}
cout << fourSW << endl << endl;
// выводим найденное

/* следующие блок кода ищет все повторяющиеся слова в тексте */
for(i=1; i<=word; i++) {
for(j=i; j<=word; j++) {
if (words[i]==words[j]) {
for(k=1; k<=repeats; k++) {
if (0==strcmp(words[i], repeatWord[k])) {
repeat[k]++;
goto n1;
}
}
repeats++;
repeatWord[repeats] = new char[lengths[i]];
repeatWord[repeats]=strdup(words[i]);
repeat[repeats]=1;
}
}
}

n1:
cout << "Repeat words: " << endl;
for (i=1; i<=repeats; i++)
if (repeat[i]>1)
cout << repeatWord[i] << " [" << repeat[i] << "], ";
// выводим слова, у которых количество повторений больше единицы

/* следующий блок кода находит цифровые слова и выводит их кубы */
cout << endl << endl << "Numeric words, and its squares: " << endl;

for (i=1; i<=word; i++) {
for(int j=0; j<lengths[i]; j++)
if (atoi(&words[i][j])==0 && words[i][j]!='0') goto n2;

sq++;
squares[sq][1]=atoi(words[i]);
squares[sq][2]=(atoi(words[i])*atoi(words[i])*atoi(words[i]));
n2:
cout << "";
}

for (i=1; i<=sq; i++)
cout << "Number: " << squares[i][1] << "; square: " << squares[i][2] << endl;

cout << endl << "------------------------------------------" << endl << endl;

// весь остальной код показывает умение работать со строковыми функциями

cout << "text1='" << text1 << "';" << endl;
cout << "text2='" << text2 << "';" << endl;

p=strstr(text1, "ov");

cout << "strcmp(text1, text2) = '" << strcmp(text1, text2) << "'" << endl;
cout << "strncmp(text1, text2, 3) = '" << strncmp(text1, text2, 3) << "'" << endl;
cout << "strlwr(text1) = '" << strlwr(text1) << "'" << endl;
cout << "strupr(text2) = '" << strupr(text2) << "'" << endl;
strrev(text1);	// функция заменяет строку
cout << "strrev(text1) = '" << text1 << "'" << endl;
strrev(text1);// возвращаем строку после вывода в исходное состояние
cout << "strspn(text2, 'ORP') = '" << strspn(text2, "ORP") << "'" << endl;
cout << "strstr(text1, 'rk') = '" << p << "'" << endl;
cout << "strchr(text1, 'r') = '" << strchr(text1, 'r') << "'" << endl;
cout << "strrchr(text1, 'r') = '" << strrchr(text1, 'r') << "'" << endl;

fp=fopen("output.txt", "w");
for(i=1; i<word; i++) {
fwrite(words[i], sizeof(char), lengths[i], fp);
fputs(", ", fp);
}
fclose(fp);

// удаляем все переменные, что мы использовали в процессе
delete repeatWord, repeats, text1, text2, text, _word, fourSW, words, lengths, digitPos, squares, sq, repeat, fp;

exit(0);

fileNotExists:
cout << "File with input data not found" << endl;
}


Не получается найти слова, не содержащие "S". Подскажите пожалуйста, будьте любезы, как доделать код для нормальной реализации данной задачи.
Буду очень признателен.
 
Код вставленный специально для показа умения работать со строковыми функциями - это мило. Жаль только весь остальной код это старательно опровергает.
Отвечая на вопрос - strchr тебя спасет с буквой S.
Замечания (можно не читать, если ты не будущий программист, а филолог выполняющий задание по информатике).
1. Сваленный в кучу код в main, в результате - goto. Все это должно быть разбито на небольшие функции и красиво записано.
2. Переменные должны всегда обнуляться при определении.
3. Чтение 150 символов в буфер длиной 149.
4. Что это?
Код:
words[word] = new char[strlen(_word)];
words[word] = _word;
А вот это?
Код:
repeatWord[repeats] = new char[lengths[i]];
repeatWord[repeats]=strdup(words[i]);
И вот это?
Код:
if (words[i]==words[j])
Явно стоит перечитать главу о работе со строками в С\С++.

5. Лень проверять, но кажется мне что atoi("21год") нормально вернет тебе 21. В любом случае atoi("год") == atoi("000"), так что не стоит ее использовать для поиска цифровых слов. strtol в лучшем случае.

И это не вдаваясь в своеобразный цикл поиска повторных слов и глубины алгоритмов - только то что глаз режет.
 
заменил
Код:
if ((fp = fopen("data.txt", "r")) == NULL) 
{
cout << "File with input data not found" << endl;
//  getch();
exit(0);
}

По поводу поиска слов без "s" переделал цикл:
Код:
for (i=1; i<=word; i++) {
if(strstr(words[i], "s")==NULL)
{
strcat(fourSW, words[i]);
strcat(fourSW, ", ");
}
}

Но вопрос - выводит все слова без "s". Подскажите пожалуйста как точно организовать цикл по подсчету количества символов, ибо необходимы только слова 5-символьной длины.
Буду очень признателен.
 
Для: o1ps
Цикл по подсчету количества символов? strlen.
 
Код:
if(strstr(words[i], "s")==NULL) 
if(strstr(words[i], "s")==NULL)) 
if (strlen(words[i], "s")==5)

??
 
Статус
Закрыто для дальнейших ответов.
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab