Загрузка данных


#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);
    }
}