我写了一个简单的程序来学习如何用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。
欢迎任何澄清或更正。
答案 0 :(得分:2)
正在发生的事情是,在使用write
致电strlen(message) + 1
时,也会写入\0
字符。
这意味着,当read()
时,\0
将附加到您的char数组中。由于printf()
在找到\0
时停止,因此这就是您第一次拨打write()
时所写内容中唯一打印文本的原因。
答案 1 :(得分:2)
+1将导致字符串末尾的零(在换行符之后),这意味着当您在另一端打印缓冲区时,printf
在第一行之后停止。我认为你真的不想发送零,所以不要这样做......
如果你真的希望字符串末尾的零通过管道,那么你必须找出每个字符串结束的位置,然后单独打印它们,例如使用strlen()
计算消息的长度,并使用在循环中移动index += strlen(&message[index])+1
和printf("%s", &message[index]);
的索引,直到您打印完所有(比较索引与您的数量)读!)。
使用循环直到read
返回零字节应该允许你读取所有输入(你现在读得太短,这就是为什么你没有得到所有的9)。