【问题标题】:pipe message in c being truncatedc中的管道消息被截断
【发布时间】:2013-08-14 23:00:57
【问题描述】:

我写了一个简单的程序来学习如何用 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 中读取并打印该消息,奇怪的是,如果我在 write(fd[1], message, strlen(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。 欢迎任何澄清或更正。

【问题讨论】:

  • 您可能想在循环中调用read 并检查返回值,直到无法读取更多内容。和/或将 MAXSIZE 设置得更大一些...
  • 问题的目的是了解 strlen 中的 +1 有何不同。如果在循环中调用 read,则必须事先知道迭代次数(或写入的消息),不是吗?
  • 如果父母的PID小于10,为什么拒绝执行读取操作?我知道pid==0 将成为fork 的孩子,你永远不会得到pid==1 因为那是init 进程,但是pids 有什么特别之处234、@987654336 @、6789?

标签: c string pipe strlen


【解决方案1】:

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

如果你真的想通过管道在字符串末尾的零,你将不得不找出每个字符串的结束位置,并单独打印它们,例如使用strlen() 来计算消息的长度,并使用在循环中移动index += strlen(&amp;message[index])+1printf("%s", &amp;message[index]); 的索引,直到您打印所有内容(将索引与您阅读的内容进行比较!)。

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

【讨论】:

  • 嗯,没意识到,感谢 Mats Petersson 的回答和建议。
【解决方案2】:

发生的情况是,当用strlen(message) + 1 调用write 时,\0 字符也会被写入。

这意味着,当read()ing 时,\0 将被附加到您的字符数组中。由于printf() 在找到\0 时停止,这就是为什么在您第一次调用write() 时所写的唯一打印文本的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-23
    • 2017-02-24
    • 1970-01-01
    • 2017-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多