两个系统上来自同一程序的C ++不同输出

时间:2017-04-21 20:58:17

标签: c++ linux

所以我正在进行一项任务,在我的笔记本电脑上工作正常,但在我的电脑上,输出是乱码。

  

输入命令:
  一个
  输入命令:
  收到a'Zéÿ命令。

忽略我混乱的输出为什么输出中有'Zéÿ? 在我的笔记本电脑上,代码按预期工作。

这是一个小样本代码:

#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <iostream>
using namespace std;

int main(){
    int pipefd[2];
    pid_t cpid, ppid;
    char buf[100];

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

    cpid = fork();

    if (cpid == 0) {
        read(pipefd[0], &buf, 1);
        cout << buf << " command received." << endl;
    }   
    else {
        cout << "Enter a command: " << endl;
        cin >> buf;
        cout << "buf: " << buf << endl;
        size_t len = strlen(buf);
        write(pipefd[1], &buf, len);
    }

    return 0;
}

尽管它的输出略有不同 收到``命令。而不是 收到命令。

E:我在我的电脑上使用了antergos,在我的笔记本电脑上使用了小学,在两个系统上终端都是urxvt

3 个答案:

答案 0 :(得分:2)

你必须初始化缓冲区,否则它将包含以前在该位置的内存中的任何内容,即正在打印的内容。

答案 1 :(得分:1)

read(pipefd[0], &buf, 1);

读取一个字节。由于它是一个字节,因此程序不太可能读取

所需的空终止符。
cout << buf << " command received." << endl;

所以打印是不明确的行为; operator<<不知道在哪里停止阅读。它可能会立即停止,它可能会在有效内存结束时运行并使程序崩溃。没有办法确定,结果可能每次都不同。

由于问题中没有协议信息,我唯一的建议是建立一个通信协议,通知读者必须读取多少字节。我喜欢在发送消息之前发送一个已知大小的计数器来通知读者消息的大小。例如,

uint32_t len = strlen(buf);
write(pipefd[1], &len, sizeof(len));
write(pipefd[1], &buf, len);

然后阅读

uint32_t len;
read(pipefd[0], &len, sizeof(len));
read(pipefd[0], &buf, len);

不要忘记检查读取是否成功并获得所需的字节数。您可能必须循环读取,直到您收到整个消息。

答案 2 :(得分:1)

read()不会自动附加空字节。您有责任在收到的消息末尾添加空字节。

最简单的方法是获取read()返回的值。此值是读取的字节数,如果遇到错误,则为-1。使用此返回值将字符串的结尾设置为null。

更改此行:

read(pipefd[0], buf, 1);

要:

int length=read(pipefd[0], buf, 99);
if (length > 0)    // length bytes was read
   buf[length]='\0';
else    // nothing was read or an error occured
   buf[0]='\0';

或者,您可以将整个缓冲区清零,这样就不需要附加空字节。

改变这个:

read(pipefd[0], buf, 1);

对此:

memset(buf,0,100);
read(pipefd[0], buf, 99);