Question

I wrote a simple program to learn how to write pipe messages in C, and while doing it I found something rather strange which i can't explain or understand, this is the code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXSIZE 100
int fd[2];

void writeMsg() {
    int i;
    char message[MAXSIZE];
    for (i = 0; i < 12; i++) {
        sprintf(message,"%d%d%d%d%d%d%d%d%d%d\n",i,i,i,i,i,i,i,i,i,i);
        write(fd[1], message, strlen(message));
    }
}

int main() {
    pipe(fd);
    char message[MAXSIZE];
    int pid;
    pid = fork();
    if (pid == 0) {
        writeMsg();
    }
    if (pid > 10) {
        wait(NULL);
        read(fd[0], message, MAXSIZE);
        printf("%s", message);
    }
    return 0;
}

In writeMsg there's a loop to write a message bigger than MAXSIZE in the pipe, after that the message is read and printed in main, the strange thing is, if I use strlen(message) in write(fd[1], message, strlen(message)) the following message is printed:

0000000000
1111111111
2222222222
3333333333
4444444444
5555555555
6666666666
7777777777
8888888888
9

But if instead i use write(fd[1], message, strlen(message)+1) the message is:

0000000000

What is the difference between strlen(message) and strlen(message)+1 ? In here http://codewiki.wikidot.com/c:system-calls:write it is said that if the number of bytes to write are smaller than the provided buffer, the output is truncated, but with +1 the string size is 11, which is not greater than MAXSIZE. Any clarification or corrections are welcome.

Was it helpful?

Solution

The +1 will cause the zero at the end of the string (after the newline) to be transmitted, which means that when you print the buffer on the other end, printf stops after the first line. You don't really want to send that zero, I think, so don't do that...

If you really want the zero at the end of the string through the pipe, you will have to then figure out where each string ends, and print them individually, e.g. using strlen() to figure out how long the message is, and use an index that moves index += strlen(&message[index])+1, and printf("%s", &message[index]); in a loop until you have printed all (compared index with how much you've read!).

Using a loop until read returns zero bytes should allow you to read all the input (you are reading too short right now, that's why you're not getting all the 9's).

OTHER TIPS

What is happening is that when calling write with strlen(message) + 1 the \0 character is also written.

That means that, when read()ing, the \0 will be appended to your char's array. Since printf() stops when it finds \0, this is the reason why the only printed text in what was written by your first call to write().

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top