#include <iostream>
#include <string>
#include <cstdlib>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char* argv[]) {
// Проверяем, передана ли строка при запуске программы.
if (argc != 2) {
std::cerr << "Использование: ./Mezhakova \"строка\"" << std::endl;
return EXIT_FAILURE;
}
int pipe_1[2]; // Передача данных от родительского процесса дочернему.
int pipe_2[2]; // Передача результата от дочернего процесса родительскому.
// Создаём первый канал.
if (pipe(pipe_1) == -1) {
perror("Ошибка создания pipe_1");
return EXIT_FAILURE;
}
// Создаём второй канал.
if (pipe(pipe_2) == -1) {
perror("Ошибка создания pipe_2");
return EXIT_FAILURE;
}
// Создаём дочерний процесс.
pid_t pid = fork();
if (pid == -1) {
perror("Ошибка fork");
return EXIT_FAILURE;
}
if (pid == 0) {
// ---------------- Дочерний процесс ----------------
// Дочерний процесс читает из pipe_1, поэтому закрываем конец записи.
close(pipe_1[1]);
// Дочерний процесс пишет в pipe_2, поэтому закрываем конец чтения.
close(pipe_2[0]);
char buffer[1024];
// Читаем строку, переданную родительским процессом.
ssize_t bytesRead = read(pipe_1[0], buffer, sizeof(buffer) - 1);
if (bytesRead == -1) {
perror("Ошибка чтения из pipe_1");
_exit(EXIT_FAILURE);
}
// Добавляем завершающий символ строки.
buffer[bytesRead] = '\0';
std::string input(buffer);
std::string result;
// Оставляем только цифровые символы.
for (char symbol : input) {
if (symbol >= '0' && symbol <= '9') {
result += symbol;
}
}
// Передаём обработанный результат родительскому процессу.
if (write(pipe_2[1], result.c_str(), result.size()) == -1) {
perror("Ошибка записи в pipe_2");
_exit(EXIT_FAILURE);
}
// Закрываем использованные файловые дескрипторы.
close(pipe_1[0]);
close(pipe_2[1]);
_exit(EXIT_SUCCESS);
}
// ---------------- Родительский процесс ----------------
// Родительский процесс пишет в pipe_1, поэтому закрываем конец чтения.
close(pipe_1[0]);
// Родительский процесс читает из pipe_2, поэтому закрываем конец записи.
close(pipe_2[1]);
std::string input = argv[1];
// Передаём исходную строку дочернему процессу.
if (write(pipe_1[1], input.c_str(), input.size()) == -1) {
perror("Ошибка записи в pipe_1");
return EXIT_FAILURE;
}
// После передачи данных закрываем конец записи.
close(pipe_1[1]);
char resultBuffer[1024];
// Получаем результат от дочернего процесса.
ssize_t bytesRead = read(pipe_2[0], resultBuffer, sizeof(resultBuffer) - 1);
if (bytesRead == -1) {
perror("Ошибка чтения из pipe_2");
return EXIT_FAILURE;
}
resultBuffer[bytesRead] = '\0';
close(pipe_2[0]);
// Ожидаем завершения дочернего процесса.
waitpid(pid, nullptr, 0);
std::cout << "Исходная строка: " << input << std::endl;
std::cout << "Результат: " << resultBuffer << std::endl;
return EXIT_SUCCESS;
}