c中的管道消息被截断

时间:2013-08-14 23:00:58

标签: c string pipe strlen

我写了一个简单的程序来学习如何用C语言编写管道消息,而在做这件事时我发现了一些我无法解释或理解的奇怪的东西,这就是代码:

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

在writeMsg中有一个循环来在管道中写一个大于MAXSIZE的消息,然后在main中读取并打印消息,奇怪的是,如果我在strlen(message)中使用write(fd[1], message, strlen(message))打印以下消息:

0000000000
1111111111
2222222222
3333333333
4444444444
5555555555
6666666666
7777777777
8888888888
9

但如果我使用write(fd[1], message, strlen(message)+1),则消息为:

0000000000

strlen(message)strlen(message)+1之间有什么区别?在这里http://codewiki.wikidot.com/c:system-calls:write,如果写入的字节数小于提供的缓冲区,则输出被截断,但是+1的字符串大小为11,不大于MAXSIZE。 欢迎任何澄清或更正。

2 个答案:

答案 0 :(得分:2)

正在发生的事情是,在使用write致电strlen(message) + 1时,也会写入\0字符。

这意味着,当read()时,\0将附加到您的char数组中。由于printf()在找到\0时停止,因此这就是您第一次拨打write()时所写内容中唯一打印文本的原因。

答案 1 :(得分:2)

+1将导致字符串末尾的零(在换行符之后),这意味着当您在另一端打印缓冲区时,printf在第一行之后停止。我认为你真的不想发送零,所以不要这样做......

如果你真的希望字符串末尾的零通过管道,那么你必须找出每个字符串结束的位置,然后单独打印它们,例如使用strlen()计算消息的长度,并使用在循环中移动index += strlen(&message[index])+1printf("%s", &message[index]);的索引,直到您打印完所有(比较索引与您的数量)读!)。

使用循环直到read返回零字节应该允许你读取所有输入(你现在读得太短,这就是为什么你没有得到所有的9)。