Home > Software engineering >  How can I add a new line at the end of the file descriptor in c?
How can I add a new line at the end of the file descriptor in c?

Time:10-30

I study the process comunications. Hello everybody. I am studying interprocess communication in C. I am using Pipes as a means of communication. Here is the exercise:

  • The child process reads from the file and inserts into the buffer, the parent process reads from the buffer and prints to the screen.

My problem is the following:

I would like to insert the string "quit \ n" at the end of the reading. Unfortunately, when the father prints on the screen, the quit string is concatenated to the last element read.

This is my code :

int main(int argc, char const *argv[])
{
     if(argc!=3)
    {
        perror(">>Error");
        exit(1);
    }
    FILE *r_file, *w_file;
    const char* filename= argv[2];
    const char* word=argv[1];
    int len=0;

    int pipefd[2];

    if (pipe(pipefd) == -1) {
        perror("pipe");
        exit(1);
    }

    if((r_file = fdopen(pipefd[0], "r"))==NULL){
        perror("reader");
        exit(1);
    }
    if((w_file = fdopen(pipefd[1], "w"))==NULL){
        perror("writer");
        exit(1);
    }

    char buffer[BUFFER_SIZE];

    if(fork()==0)//child R
    {
        FILE* file;
        if((file=fopen(filename,"r"))==NULL)
        {
            perror("fopen");
            exit(1);
        }

        close(pipefd[0]);
        char* n;
        while((n=(fgets(buffer,BUFFER_SIZE,file)))!=NULL)
        {
            
            printf("leggo:%s",buffer );
            fputs(buffer,w_file);

        }

        fputs("quit\n",w_file);
        
        
        fclose(file);
        exit(0);

    }
    else
    {
        printf("- Sono il padre\n");
        close(pipefd[1]);
        while(fgets(buffer,BUFFER_SIZE,r_file)>0)
        {
            
            len=strlen(buffer);
            if(buffer[len-1]=='\n') buffer[len-1]='\0';
         
           
            printf("\nbuffer: %s", buffer);
          

        }

    }
    

}

and this is my output:

leggo:House 
leggo:Hello
leggo:Car
leggo:Moto
leggo:House
leggo:Mouse
leggo:City
leggo:Alex
leggo:PC
leggo:Hello
leggo:Hello
buffer: House 
buffer: Hello
buffer: Car
buffer: Moto
buffer: House
buffer: Mouse
buffer: City
buffer: Alex
buffer: PC
buffer: Hello
buffer: Helloquit% 

as you see

as you see, my last line is

"buffer: Helloquit%". 

But I wish that my last line will be

"buffer: quit"

Help me please !!

CodePudding user response:

That is just a problem in your file. If the last line of your file (containing "Hello") doesn't end with a \n then the 2 last things you fputs to your parent is "Hello" (without a \n) and then "quit\n".

So then, the last line your parent will read (it has strictly no way to know you send those in 2 steps. What it does is just reading every till it encounter an EOF or a \n) is "Helloquit\n"

As for the % it is probably the prompt of your shell.

Because, in the parent, you remove the \n from what you receive. But then print with a \n at the beginning of the line. Reason why you still print 1 word per line. But then the last line (independently of the concatenation Hello quit problem) is printed without a ending \n.

So, correction:

  • For the concatenation Hello quit problem. Either just correct your input file. Or, do in the child the same thing you did with the parent: remove the \n if there is one, from the lines you read. And then add it again yourself before fputs (or fprintf, like this fprintf(w_file, "%s\n", buffer)). So that you know that each line is ended with a \n in the communication with parent, whether there was one in the file or not.
  • For the last line ending with % (prompt of your shell), just add a printf("\n") at the end. Or, replace the printf("\n%s", buffer) by a more logical printf("%s\n", buffer). I suspect you've chosen this strange position of \n because otherwise the line is sometimes concatenated with the last "Hello" that doesn't end with a newline. But we have solved that now.

Anyway, we don't really know in which order the print will occur, since you have 2 independent process. In your demo, it occurs in an apparently orderly fashion, because w_file is not an interactive file, so flush occurs only when buffer (not yours, the internal buffer of FILE) is full, or when file is closed (if w_file was interactive, as stdout is, then buffer is also flushed at each newline). So, you can't assume anything about how printf from child and printf from parent will be intricated on the shared display they have. But I am pretty sure, those are only debugging messages anyway, so you don't really care, do you? (you shouldn't, at least)

  • Related