0

I am trying to create a code implementing pipelining to get the characters in an input file ("input.txt") and have the program capitalize the lowercase letters and vice versa. Here is my code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <ctype.h>

//This program takes the other program and implements pipelining to make it more efficient

int main() {
    
    //Defining the 2 child processes
    pid_t ChildProcess1, ChildProcess2;
    
    //Now to create the two pipes
    int fd1[2], fd2[2];

    FILE *inputFile = fopen("input.txt", "r");
    FILE *outputFile = fopen("output.txt", "w");
    
    /*Parent Process
    char string[500];
    while (fgets(string, sizeof(string), inputFile) != NULL) 
    {
        close(fd2[0]); // closing unused read end of second pipe
        write(fd1[1], string, strlen(string) + 1); // writing to first pipe
        close(fd1[1]); // closing write end of first pipe

        wait(NULL); // waiting for child process 1 to finish

        read(fd2[0], string, 500); // reading from second pipe

        printf("%s", string); // printing the output from the second child process

        // resetting the line
        memset(string, 0, sizeof(string));
    }*/
    
    //Process 1: Input text and change lowercase to uppercase and vice versa
    ChildProcess1 = fork(); // creating first child process

    if (ChildProcess1 == 0) { 
        close(fd1[1]); 

        char string[500];
        read(fd1[0], string, 500);

        /*for (int i = 0; i < strlen(string); i++) {
            
            if (string[i] >= 'A' && string[i] <= 'Z') 
            {
                string[i] = string[i] + 32; // convert uppercase to lowercase
            }
            else if (string[i] >= 'a' && string[i] <= 'z') 
            {
                string[i] = string[i] - 32; // convert lowercase to uppercase
            }
            else
            {
                printf("A non-alphabetical character has been detected. This character is skipped over");
            }
            
        }
        */
        
        for (int i = 0; string[i] != '\0'; i++) {
            
            char Character = string[i];
            
            if (islower(Character)) { // if the character is lowercase
                string[i] = toupper(Character); // convert it to uppercase
            } 
            
            else if (isupper(Character)) { // if the character is uppercase
                string[i] = tolower(Character); // convert it to lowercase
            }
            
            else {
                printf("A non Alphabetical letter has been detected. Therefore, it is ignored");
            }
            
        }

        close(fd1[0]); // closing read end of first pipe
        close(fd2[0]); // closing unused read end of second pipe
        
        write(fd2[1], string, strlen(string) + 1); // writing to second pipe
        close(fd2[1]); // closing write end of second pipe

        exit(0); // exit child process 1
    }
    
    //The second process, where the newly generated text is put into a new output text file
    ChildProcess2 = fork();

    if (ChildProcess2 == 0) { // child process 2
    
        close(fd2[1]); // closing write end of second pipe

        char string[500];
        read(fd2[0], string, 500); // reading from second pipe

        fprintf(outputFile, "%s", string); // writing to output file

        close(fd2[0]); // closing read end of second pipe

        exit(0); // exit child process 2
    }

    // parent process
    char string[500];
    while (fgets(string, sizeof(string), inputFile) != NULL) 
    {
        close(fd2[0]); // closing unused read end of second pipe
        write(fd1[1], string, strlen(string) + 1); // writing to first pipe
        close(fd1[1]); // closing write end of first pipe

        wait(NULL); // waiting for child process 1 to finish

        read(fd2[0], string, 500); // reading from second pipe

        printf("%s", string); // printing the output from the second child process

        // resetting the line
        memset(string, 0, sizeof(string));
    }

    close(fd1[1]); // closing write end of first pipe
    close(fd2[0]); // closing read end of second pipe

    wait(NULL); // waiting for child process 2 to finish

    fclose(inputFile); // closing input file
    fclose(outputFile); // closing

    return 0;
    
}

I am required to use multiple processes exchanging data via pipes.

I intend for this program to read the character string from an input text file, capitalize the lower case letters and vice versa, and write the result an output text file. For example, I inputted the character string "characterstring". The program seemed to run without any errors, but all it does is reprint this string out onto the console without any capitalization. Nothing appears in the output text file.

What's wrong?

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • 1
    Am I missing something or are you missing calls to `pipe(fd1)` and `pipe(fd2)`? – EdmCoff Mar 20 '23 at 14:39
  • It's not obvious to me why you think involving multiple processes will provide a significant improvement in efficiency for this task. Get a single-process version of your code working first. If you have some requirement to implement a multiprocessing version, then add the multiprocessing later. – John Bollinger Mar 20 '23 at 14:44
  • I understand, but the use of pipelining and forking is required for me to use in this program. – Thomas Kent Mar 20 '23 at 14:49
  • 1
    `//Now to create the two pipes` - you seem to have forgotten to do that. All you did was declare two automatic `int[2]` arrays. There are no descriptors stored in either (that you obtained from legitimate calls, anyway). – WhozCraig Mar 20 '23 at 15:00
  • Please delete the commented-out code blocks. They do not contribute anything to the question. – John Bollinger Mar 20 '23 at 15:20
  • You say that the program seems to run without errors, but you're not *checking* for errors. If you care about errors -- and you do -- you need to check the return values of your function calls to watch for failures, and to provide appropriate handling when they occur. In the case of some functions, including `read()` and `write()`, the return values contain essential information beyond success / failure status, which your program needs to use to modulate its behavior. At least, if it is to be robust. – John Bollinger Mar 20 '23 at 15:27

0 Answers0