Использование любых разделителей для разбивки строки на подстроки - C (СИ)
Формулировка задачи:
Второй раз создаю такую тему, но что ж поделать, предыдущий ответ не подошёл, да и код немного изменился.
Помогите, если не трудно.
Проблема вот в чём: я ввожу текст, делаю преобразования и новый текст получается разделённый только пробелами - да, я сам так и сделал, но иного придумать не могу.
Как сделать так, чтобы текст был отделён теми же разделителями, которые были в изначальном?
Код таков:
// ConsoleApplication1.cpp: определяет точку входа для консольного приложения.
//
#include "stdafx.h"
#include "stdio.h"
#include "windows.h"
#include "iomanip"
#include "string.h"
int main()
{
setlocale(LC_ALL, "Russian"); //Установка русского языка
FILE *from_file, *in_file; //Указатели для файлов
printf("Открытие файла для вывода текста:"); //Открытие
fopen_s(&in_file, "D:\\Kursovaia\\Vivod.txt", "w"); //файла для вывод текста
if (in_file == NULL) printf("ошибка\n"); //и
else printf("выполнено\n"); //проверка
printf("Открытие файла с символами-разделителями:"); //Открытие
fopen_s(&from_file, "D:\\Kursovaia\\Delimiters.txt", "r"); //файла с символами-разделителями
if (from_file == NULL) printf("ошибка\n"); //и
else printf("выполнено\n"); //проверка
char glasnie[13] = "aeiouyAEIOUY"; //Введём массив гласных и
int vowels = 0; //обнулим их начальное количество в тексте
char *delimeters; //Введём массив разделителей из файла
delimeters = (char*)malloc(5 * sizeof(char)); //и
fgets(delimeters, 5, from_file); //выделим под него память
int uslovie;
printf("Введите количество гласных:\n"); //Условие остановки ввода текста
scanf_s("%d", &uslovie);
getchar();
int preobrazovanie;
printf("Введите количество букв, длиннее которого вы не хотите видеть слова в тексте:\n"); //Условие преобразования текста
scanf_s("%d", &preobrazovanie);
getchar();
char *lol;
char *str;
char *text;
text = (char*)malloc(sizeof(char)); //Введём текст,
int i = 0; //соблюдая
printf("Введите текст:\n"); //условие
while (vowels < uslovie)
{
text[i] = getchar();
for (int m = 0; m < 14; m++)
{
if (text[i] == glasnie[m])
{
vowels++;
}
}
i++;
text = (char*)realloc(text, (i + 1)*sizeof(char));
}
text[i] = '\0';
printf("Введённый вами текст:\n%s\n", text);
lol = strtok_s(text, delimeters, &str);
while (lol)
{
if (strlen(lol) <= preobrazovanie)
{
fprintf(in_file, "%s ", lol);
}
lol = strtok_s(NULL, delimeters, &str);
}
fclose(in_file); //Закроем файлы
printf("Файл для вывода текста закрыт\n"); //для вывода текста
fclose(from_file); //и
printf("Файл с символами-разделителями закрыт\n"); //с символами-разделителями
free(delimeters); //Правила
free(text); //хорошего
system("pause"); //тона
return 0;
}
UP!
P.S. Посмотрел все темы, решение есть, но всего одно или два и слишком для меня трудные.
Во всех остальных подобных случаях слова разделены лишь пробелом, а у меня они разделены могут быть чем угодно.
UP!
Приму любой совет, не обязательно писать код.
Напомню в чём заключается программа: останавливает ввод при достижение определённого количества гласных и удаляет слова длиннее определённой длины, слова могут быть разделены разделителями из файла.
Решение задачи: «Использование любых разделителей для разбивки строки на подстроки»
textual
Листинг программы
// ConsoleApplication1.cpp: определяет точку входа для консольного приложения.
//
#include "stdafx.h"
#include "stdio.h"
#include "windows.h"
#include "iomanip"
#include "string.h"
#include "malloc.h"
int main()
{
setlocale(LC_ALL, "Russian"); //Установка русского языка
FILE *from_file, *in_file; //Указатели для файлов
printf("Открытие файла для вывода текста:"); //Открытие
fopen_s(&in_file, "D:\\Kursovaia\\Vivod.txt", "w"); //файла для вывод текста
if (in_file == NULL) printf("ошибка\n"); //и
else printf("выполнено\n"); //проверка
printf("Открытие файла с символами-разделителями:"); //Открытие
fopen_s(&from_file, "D:\\Kursovaia\\Delimiters.txt", "r"); //файла с символами-разделителями
if (from_file == NULL) printf("ошибка\n"); //и
else printf("выполнено\n"); //проверка
char glasnie[13] = "aeiouyAEIOUY"; //Введём массив гласных и
int vowels = 0; //обнулим их начальное количество в тексте
char *delimeters; //Введём массив разделителей из файла
delimeters = (char*)malloc(5 * sizeof(char)); //и
fgets(delimeters, 5, from_file); //выделим под него память
int uslovie;
printf("Введите количество гласных:\n"); //Условие остановки ввода текста
scanf_s("%d", &uslovie);
getchar();
int preobrazovanie;
printf("Введите количество букв, длиннее которого вы не хотите видеть слова в тексте:\n"); //Условие преобразования текста
scanf_s("%d", &preobrazovanie);
getchar();
char *lol;
char *str;
char *text;
text = (char*)malloc(sizeof(char)); //Введём текст,
int i = 0; //соблюдая
printf("Введите текст:\n"); //условие
while (vowels < uslovie)
{
text[i] = getchar();
for (int m = 0; m < 14; m++)
{
if (text[i] == glasnie[m])
{
vowels++;
}
}
i++;
text = (char*)realloc(text, (i + 1)*sizeof(char));
}
text[i] = '\0';
printf("Введённый вами текст:\n%s\n", text);
char* pos = text; // указатель на текущий символ в строке для разюора
lol = strtok_s(text, delimeters, &str);
while (strchr(delimeters, *pos))
putchar(*pos++); // выводим разделители в начале строки(если есть)
while (lol)
{
size_t len = strlen(lol);
if (len <= preobrazovanie)
{
fprintf(in_file, "%s", lol); // убираем пробел
}
pos += len;
while (strchr(delimeters, *pos))
{
fputc(*pos++, in_file);
} // выводим разделители
lol = strtok_s(NULL, delimeters, &str);
}
fclose(in_file); //Закроем файлы
printf("Файл для вывода текста закрыт\n"); //для вывода текста
fclose(from_file); //и
printf("Файл с символами-разделителями закрыт\n"); //с символами-разделителями
free(delimeters); //Правила
free(text); //хорошего
system("pause"); //тона
return 0;
}
Объяснение кода листинга программы
- Объединение и связывание всех вводимых строк в одну большую строку.
- Разделение большой строки на подстроки по определенным правилам (например, по количеству гласных).
- Присваивание каждой подстроке уникального идентификатора (например, номера).
- Сохранение полученных подстрок в файл для дальнейшего использования.
- Использование функций работы со строками для обработки и преобразования этих подстрок (например, удаление пробелов).
- Использование функций работы с файлами для чтения и записи данных в файл.
- Использование функций работы с памятью для выделения и освобождения памяти, используемой этими подстроками и идентификаторами.
- Использование условных операторов и циклов для контроля и управления процессом объединения, разделения и обработки строк.
- Ввод и вывод данных с помощью функций scanf_s и printf, а также функций ввода-вывода файлов fopen, fgets, fprintf, fputc и fclose.
- Использование функции realloc для динамического изменения размера выделенной памяти.
- Использование функции strlen для определения длины строки.
- Использование функции strtok_s для разделения строки на подстроки по определенным разделителям.
- Использование функции getchar для чтения символов из стандартного ввода.
- Использование функции system для выполнения системной команды (в данном случае, для приостановки выполнения программы до нажатия клавиши).
- Использование функции free для освобождения памяти, выделенной функцией malloc.
- Использование функции putchar для вывода символов в стандартный вывод.
- Использование функции sprintf для форматирования и записи строки в файл.
- Использование функции isalpha для проверки, является ли символ буквой.
- Использование функции strchr для поиска первого вхождения символа в строке.
- Использование функции memset для очистки выделенной памяти.