#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
// Функция заменяет последовательности из одного или более '_' на один '_'
void compress_underscores(const char *src, char *dst) {
int j = 0;
int prev_underscore = 0;
for (int i = 0; src[i] != '\0'; i++) {
if (src[i] == '_') {
if (!prev_underscore) {
dst[j++] = '_';
prev_underscore = 1;
}
} else {
dst[j++] = src[i];
prev_underscore = 0;
}
}
dst[j] = '\0';
}
int main() {
int pipe1[2], pipe2[2];
pid_t cpid;
char input[4096];
char result[4096];
// Запрос строки у пользователя
printf("Enter a string with words separated by '_' (multiple underscores allowed): ");
if (fgets(input, sizeof(input), stdin) == NULL) {
fprintf(stderr, "Error reading input\n");
exit(EXIT_FAILURE);
}
// Удаляем символ новой строки, если он присутствует
size_t len = strlen(input);
if (len > 0 && input[len - 1] == '\n') {
input[len - 1] = '\0';
}
// Создаём два канала
if (pipe(pipe1) == -1 || pipe(pipe2) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
cpid = fork();
if (cpid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0) { // Дочерний процесс
// Закрываем ненужные концы:
// для pipe1 – запись, для pipe2 – чтение
close(pipe1[1]);
close(pipe2[0]);
char buffer[4096];
ssize_t n = read(pipe1[0], buffer, sizeof(buffer) - 1);
if (n < 0) {
perror("read");
exit(EXIT_FAILURE);
}
buffer[n] = '\0';
// Обработка строки: удаление лишних '_'
char processed[4096];
compress_underscores(buffer, processed);
// Отправляем результат родителю через pipe2
write(pipe2[1], processed, strlen(processed));
// Закрываем оставшиеся концы и завершаем дочерний процесс
close(pipe1[0]);
close(pipe2[1]);
_exit(EXIT_SUCCESS);
} else { // Родительский процесс
// Закрываем ненужные концы:
// для pipe1 – чтение, для pipe2 – запись
close(pipe1[0]);
close(pipe2[1]);
// Передаём исходную строку через pipe1
write(pipe1[1], input, strlen(input));
close(pipe1[1]);
// Читаем обработанную строку из pipe2
ssize_t n = read(pipe2[0], result, sizeof(result) - 1);
if (n < 0) {
perror("read");
exit(EXIT_FAILURE);
}
result[n] = '\0';
// Выводим результат
printf("Result: %s\n", result);
close(pipe2[0]);
wait(NULL); // Ожидаем завершения дочернего процесса
exit(EXIT_SUCCESS);
}
}