Handling Pipe Synchronization and Process Communication in C for Reading and Processing CSV Data

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h> 
#include <unistd.h>
#include <ctype.h>
#include <wctype.h>

// Structure to represent an object with string, frequency, occurrence, and coordinates
typedef struct {
    char String[30];
    float frequency;
    int occurrence;
    int x;
    int y;
} object;

// Structure for a matrix containing a list of objects and its dimensions
typedef struct {
    object** list;
    int* x;
    int y;
} matrix;

// Structure to represent an alphabet node
struct Alphabet {
    struct Alphabet* subAlphabet[31];
    object* word;
};

// Define Dictionary as a pointer to Alphabet struct
typedef struct Alphabet Dictionary;

// Declaration of the recursive deallocation function
Dictionary* deallocation(Dictionary* dict);

// Function to get the ASCII index of a character
int asciiIndex(char character) {
    // Maps characters A-Z, a-z, !, ?, ., and ' to ASCII values
    if ((character >= 'A' && character <= 'Z')) { 
        return (int)(character - 'A');
    } else if ((character >= 'a' && character <= 'z')) { 
        return (int)(character - 'a');
    } else if (character == '!') {
        return 27;
    } else if (character == '?') {
        return 28;
    } else if (character == '.') {
        return 29;
    } else if (character == ''') {
        return 30;
    }
    return '';
}

// Function to compare two strings
bool compareStrings(char* string1, char* string2) {
    // Checks if the two strings are equal, considering case insensitivity
    if ((int)*string1 == (int)*string2 || ((int)*string1 + 32) == (int)*string2 || ((int)*string1 - 32) == (int)*string2) {
        // Strings are equal or differ only by case
    } else {
        // Strings are different
        return false;
    }

    // If both strings have reached the end, they are equal
    if ((*string1 || *string2) == '') {
        return true;
    } else {
        // Otherwise, compare the next characters recursively
        compareStrings((string1 + 1), (string2 + 1));
    }
}

// Function for operational search of a string in the matrix
int operationalSearch(char string[], int index, Dictionary* dict, int y, matrix* m) {
    // Initialize the current dictionary
    Dictionary* currentDict = dict;
    int ASCII;

    // If the end of the string is reached, compare strings or add the new word
    if (string[index] == '') {
        printf("%s = %sn", currentDict->word->String, string);
 
        if (compareStrings(currentDict->word->String, string) == 1) {
            return currentDict->word->y;
        } else {
            // Add the new word to the dictionary
            strcpy(currentDict->word->String, string);
            currentDict->word->y = y;
            printf("stored: %sn", currentDict->word->String);
            return -1;
        }
    }

    // The word is not present in the matrix, so add it to the dictionary
    ASCII = asciiIndex(string[index]);
    if (currentDict->subAlphabet[ASCII] == NULL) {
        currentDict->subAlphabet[ASCII] = (Dictionary*)calloc(1, sizeof(Dictionary));
        if (currentDict->subAlphabet[ASCII] == NULL) {
            exit(1);
        }
        currentDict->subAlphabet[ASCII]->word = (object*)malloc(sizeof(object));
        if (currentDict->subAlphabet[ASCII]->word == NULL) {
            exit(1);
        }
        // Initialize the allocated memory to zero
        memset(currentDict->subAlphabet[ASCII]->word, 0, sizeof(object));
    }
    currentDict = currentDict->subAlphabet[ASCII];
    return operationalSearch(string, index + 1, currentDict, y, m);
}

// Function to print the string and recursively call itself
void printString(char String[30], matrix m, Dictionary* dict, int y, int generatedWords, int generatedWordCount, FILE* outputFile, int pipe2[], char selectedWord[30]) {
    if (generatedWordCount == generatedWords) { // base case
        fprintf(outputFile, "n");
        return;
    }

    printf("%sn", String);
    fprintf(outputFile, "%s", String);
    if (m.list[y][1].frequency == 1.0) {
        y = operationalSearch(m.list[y][1].String, 0, dict, y, &m);
    } else {
        int numElementsRow = m.x[y];
        // Iterate through words and select one based on probability
        srand(clock()); // use clock ticks as seed for random generator
        float randomNum = (float)rand() / RAND_MAX;
        for (int i = 1; i < numElementsRow; ++i) {

            if (randomNum < m.list[y][i].frequency) {
                printf("%s repeatedn", m.list[y][i].String);
                y = operationalSearch(m.list[y][i].String, 0, dict, y, &m);
                break;
            } else {
                // Subtract the probability of the current word
                randomNum -= m.list[y][i].frequency;
            }
        }
    }
    printf("middle: %sn", m.list[y][0].String);
    fprintf(outputFile, " ");
    return printString(m.list[y][0].String, m, dict, y, generatedWords, generatedWordCount + 1, outputFile, pipe2, selectedWord);
}

// Function to read CSV file and write words to the pipe
void readCSV(FILE* file, int pipe1[]) {
    char buffer[31]; // Buffer to read words
    char character;
    int bytesRead;

    while (1) {
        bytesRead = fscanf(file, "%30[^,n]", buffer);
        if (bytesRead == 1) {
            write(pipe1[1], buffer, sizeof(buffer));
        } else {
            break;
        }
        printf("%s|", buffer);
        character = fgetc(file); // Read the next character

        if (character == 'n') {
            strcpy(buffer, "n"); // Add a newline to the buffer
            printf("%s", buffer);
            write(pipe1[1], buffer, sizeof(buffer));
        } else if (character == EOF) {
            break;
        }
    }

    close(pipe1[1]);
}

// Function to create the matrix and populate it from the pipe data
void createMatrix(matrix* m, int pipe1[], int pipe2[], Dictionary* dict) {
    char string1[31];
    int* capitalIndexes = NULL;
    int capitals = 0;
    int columnIndex = 0;
    int rowIndex = 0;

    capitalIndexes = malloc(sizeof(int));
    if (capitalIndexes == NULL) {
        perror("Memory allocation error");
        exit(EXIT_FAILURE);
    }

    while (read(pipe1[0], string1, sizeof(string1)) > 0) {
        printf("%c", string1[0]);
        if (isalpha(string1[0]) || iswalpha(string1[0])) {
            if (m->x[m->y - 1] - 1 != 0) { // if the previous string stored in the matrix is the key
                m->x[m->y - 1]++;
                m->list[m->y - 1] = realloc(m->list[m->y - 1], m->x[m->y - 1] * sizeof(object));
            }

            strcpy(m->list[m->y - 1][m->x[m->y - 1] - 1].String, string1);

        } else if (isdigit(string1[0])) {
            m->list[m->y - 1] = realloc(m->list[m->y - 1], m->x[m->y - 1] * sizeof(object));
        } else if (string1[0] == 'n') {
            m->y++;
            m->list = realloc(m->list, m->y * sizeof(object*));
            m->x = realloc(m->x, m->y * sizeof(int));
            m->list[m->y - 1] = NULL;
            m->x[m->y - 1] = 0;
        }
    }

    printf("cnnn");
    // Print the matrix
    for (int i = 0; i < m->y - 1; i++) {
        for (int j = 0; j < m->x[i]; j++) {
            if (j == 0) {
                printf("%s ", m->list[i][j].String);
            } else {
                printf(",%s,%.4f ", m->list[i][j].String, m->list[i][j].frequency); // Print the frequency value of the element
            }
        }
        printf("n");
    }

    close(pipe1[0]);
    close(pipe2[1]);
}

// Main function
int main() {
    Dictionary* dict = (Dictionary*)calloc(1, sizeof(Dictionary));
    dict->word = (object*)malloc(sizeof(object));

    FILE *file = fopen("controprova.csv", "r");
    if (file == NULL) {
        fprintf(stderr, "Error opening file.n");
        return 1;
    }
    FILE *outputFile = fopen("prova1.txt", "w");

    char selectedWord[30] = "";
    int generatedWords = 30;

    int pipe1[2], pipe2[2];

    if (pipe(pipe1) == -1 || pipe(pipe2) == -1) {
        exit(EXIT_FAILURE);
    }

    // Initialize the matrix structure
    matrix* m = (matrix*)malloc(sizeof(matrix));
    m->list = NULL;
    m->x = NULL;
    m->y = 0;

    pid_t pid1, pid2, pid3;

    pid1 = fork();
    if (pid1 == -1) {
        perror("Fork error");
        return 1;
    } else if (pid1 == 0) {
        printf("Process 1: %dnn", getpid());
        close(pipe1[0]);
        readCSV(file, pipe1);
        exit(0);
    }

    pid2 = fork();
    if (pid2 == -1) {
        printf("Fork error");
        return 1;
    } else if (pid2 == 0) {
        printf("nnProcess 2: %dnn", getpid());
        close(pipe1[1]); // Close pipe1[1] in the child process
        close(pipe2[0]);
        createMatrix(m, pipe1, pipe2, dict);
        exit(0);
    }

    pid3 = fork();
    if (pid3 == -1) {
        perror("Fork error");
        return 1;
    } else if (pid3 == 0) {
        printf("nnProcess 3: %dn", getpid());
        close(pipe2[1]);
        // ... (code for process 3) ...
        exit(0);
    }

    free(m->list);
    free(m->x);
    free(m);

    // Deallocate the dictionary (words and structure)
    for (int i = 0; i < 30; i++) {
        dict->subAlphabet[i] = deallocation(dict->subAlphabet[i]);
    }
    free(dict->word);
    free(dict);

    return 0;
}

// Recursive deallocation function
Dictionary* deallocation(Dictionary* dict) {
    if (dict == NULL) {
        return NULL;
    }

    for (int i = 0; i < 30; i++) {
        dict->subAlphabet[i] = deallocation(dict->subAlphabet[i]);
    }
    free(dict->word);
    free(dict);
    return NULL;
}

I am a beginner in C programming and I am working on a project that involves reading a CSV file, processing its content, and then generating some output. The project involves three processes:

  1. The first process reads the CSV file and writes the words to a pipe.

  2. The second process reads from the pipe, constructs a matrix structure, and stores the words along with their frequencies.

  3. The third process (yet to be implemented) will use the matrix to generate output based on the processed data.

I am facing issues with the synchronization of these processes, particularly with ensuring that the pipes are not closed prematurely, which leads to communication problems between the processes. I need help understanding how to properly manage pipe read/write operations and process synchronization to avoid these issues. Additionally, I need to ensure that the matrix structure is correctly populated and that memory allocation is handled properly.

I have tried implementing three processes to handle reading, processing, and outputting data from a CSV file. Here is what I did:

  1. Reading CSV (Process 1): This process reads the CSV file, splits the words, and writes them to a pipe.

  2. Constructing the Matrix (Process 2): This process reads the words from the pipe, constructs a matrix structure, and stores the words along with their frequencies.

  3. Generating Output (Process 3): This process is yet to be implemented. It is supposed to use the matrix to generate and print the output based on the processed data.

Expected Outcome: I expected the second process to read from the pipe correctly and construct the matrix. Specifically, I expected the matrix to be printed on the screen, showing each word and its corresponding frequency using nested for loops.

Actual Outcome: The matrix is not being constructed correctly. The processes are facing synchronization issues, likely due to premature closing of the pipes or incorrect handling of read/write operations. This results in incomplete or incorrect data being read and processed, leading to an incorrect or empty matrix being printed.

I need help ensuring proper synchronization between the processes and correct handling of pipe operations to achieve the expected outcome.

input CSV:
.,What,1.0000

What,do,1.0000

do,the,1.0000

the,forecasts,1.0000

forecasts,of,0.6667,weather,0.3333

of,time,1.0000

time,?,0.3333,of,0.3333,uncertain,0.3333

?,Forecasts,1.0000

of,today,0.5000,tomorrow,0.5000

today,time,1.0000

uncertain,!,1.0000

!,Forecasts,1.0000

tomorrow,?,1.0000

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật