gpt4 book ai didi

c++ - 将管道与字符串数组一起使用

转载 作者:行者123 更新时间:2023-11-28 01:52:32 24 4
gpt4 key购买 nike

尝试创建一个可以计算出一串随机数的管道。拆分为 parent 和 child ,生成随机数,如果是 child 则写入管道,如果是 parent 则读取。我觉得这很接近,但我的输出是无稽之谈。有人可以解释一下管道的作用,并为我指明正确的方向以执行此操作。

    #include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream> /* c++ I/O headers */
#include <string.h>
#include<math.h>

using namespace std;

int main(int argc, char *argv[]) {

//Get the number of random numbers
int numberOfRandomNumbers = stoi(argv[1]);

//char childPipe[200], parentPipe[200]; //pipes to hold numbers
int pid, index, count; //counters
int pipe1[2]; // main pipe

int xyz = pipe(pipe1); //perform the pipe
string stringOfRandomNumbers = "";

pid = fork(); //fork the process

//check for errors-------------------------------------------
if(xyz < 0 || pid < 0){
//break
cout << "Error" << endl;
return 0;
}

//Check process----------------------------------------------

if (pid == 0) { /* child */

srand(pid+4); //seed the random
int randNum;


//Start building the string
stringOfRandomNumbers = "Child, ID = ";
stringOfRandomNumbers += to_string(pid);
stringOfRandomNumbers += ", Random numbers: >";


//Now generate random numbers
for (index = 0; index < numberOfRandomNumbers; index++) {

randNum = rand() % 100;

//add to string.....
if(index == (numberOfRandomNumbers - 1)){
//last one
stringOfRandomNumbers += (to_string(randNum) + "<");
}
else{

stringOfRandomNumbers = stringOfRandomNumbers + (to_string(randNum) + ", ");

}

}

cout << endl << stringOfRandomNumbers << " length = " << stringOfRandomNumbers.length() << endl;

close(pipe1[0]); //don't read off of pipe
write(pipe1[1], stringOfRandomNumbers, stringOfRandomNumbers.length());
close(pipe1[1]); //done

}

else { /* parent */


// Now generate random numbers
srand(pid+8);
int randNum;

//Start the string
stringOfRandomNumbers = "Parent, ID = ";
stringOfRandomNumbers += to_string(pid);
stringOfRandomNumbers += ", Random numbers: >";


//Now generate random numbers
for (index = 0; index < numberOfRandomNumbers; index++) {

randNum = rand() % 100;

//Add to string.....
if(index == (numberOfRandomNumbers - 1)){
//last one
stringOfRandomNumbers += (to_string(randNum) + "<");
}
else{

stringOfRandomNumbers = stringOfRandomNumbers + (to_string(randNum) + ", ");
}
}

close (pipe1[1]);

count = read(pipe1[0], stringOfRandomNumbers, stringOfRandomNumbers.length());

for (index=0; index < count; index++){
cout << stringOfRandomNumbers[index] << endl;
}
close (pipe1[0]); //done
}
}

最佳答案

readwrite 是老式的 C 函数。他们不知道 C++ 字符串是什么,他们退而求其次假设 stringOfRandomNumbers 是指向您要发送的数据或您希望接收的缓冲区的指针。

stringOfRandomNumbers 不是指针,您应该从编译器那里收到一条警告消息,如果不是完全拒绝编译的话。即使它是一个指针,std::string 也不一定直接包含它所代表的数据。通常情况下,std::string 指向一个动态分配的存储 block ,如果您编写 std::string,你写的是指针而不是指向的数据。

接收 std::string 现在有一个指向内存的指针,它在发送过程中有意义,但在接收过程中毫无意义或危险。如果两者都在同一个进程中,那么内存仍然有效,但是你有两个 std::string 指向同一个内存。一旦其中一个 std::string 超出范围,它将删除内存并让另一个 std::string 指向无效内存。

无论如何都是一个非常糟糕的场景。

接下来,因为您将发送 std::string 对象,而不是字符串数据,所以如果字符串数据的长度与 sizeof(std::string) 因此将发送垃圾数​​据或发送的数据不足。

你想做的是

write(pipe1[1], stringOfRandomNumbers.c_str(), stringOfRandomNumbers.length()+1);

std::string::c_str 获取指向包含字符串数据的缓冲区的指针,+1 发送缓冲区的终止 null,以便接收方知道字符串停止的位置。

这种方法给您带来了一个问题:我需要读取多少数据?您必须继续从管道读取并将读取的内容附加到 std::string 直到找到 null。有点恶心。

但是

uint32_t len = stringOfRandomNumbers.length();
write(pipe1[1], &len, sizeof(len));
write(pipe1[1], stringOfRandomNumbers.c_str(), len);

首先将字符串的长度写入 32 位无符号整数,然后从 stringOfRandomNumbers 缓冲区写入 len 字节。

警告:uint32_t 是可选的,您的编译器可能不支持它。这个想法是为了确保两台​​ PC 都确切知道长度有多大,因此您可能必须找到发送方和接收方都同意的固定大小。

在接收端,

uint32_t len;
read(pipe1[0], &len, sizeof(len)); //read len
std::vector<char> buffer(len+1); // Make buffer big enough for string and terminating null
read(pipe1[0], buffer.data(), len); // read into buffer
buffer[len] = '\0'; // null terminate
stringOfRandomNumbers = buffer.data();

C++17 标准预计会使这更容易一些,因为您将能够从 std::string 请求非const 数据指针.提前调整 std::string 的大小,您可以安全地直接读入它。

关于c++ - 将管道与字符串数组一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42426486/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com