我正在读一根烟斗。
char buf[255];
while((nbytes = read(fd,buf,sizeof(buf)) > 0)) // fd is the opened pipe
{
if(strcmp(buf,"IN")==0){
printf("%s\n", "SET IN");
}
if(strcmp(buf,"OUT")==0){
printf("%s\n", "SET OUT");
}
}
现在我通过终端写入管道
echo "OUT" > /path/to/FIFO
我得到的输出是:“SET IN”
我键入的所有内容我总是以“SET IN”作为输出。我如何比较我从管道中读取的字符串?
答案 0 :(得分:1)
您将读取数据视为字符串(通过将其传递给strcmp()
),但无法保证输入数据以0结尾。特别是,read()
不会终止数据,如果可能的话,它会用数据填充整个缓冲区。
您需要通过将读取调用修改为:
来自行完成while((nbytes = read(fd, buf, sizeof buf - 1)) > 0 ) // fd is the opened pipe
{
buf[nbytes - 1] = '\0';
请注意,传递给read()
的大小已缩小,以便为终结符腾出空间,并且我们会添加它。
另请注意,我更正了while
中的括号,如上面@AhmedMasud的评论中所述。这是一个好点,我忘了强调它。
更新:如xaxxon's answer所述,数据将以不可预测的块传递,因此协议可能很有用。流经管道的文本数据最简单的协议是(当然?)基于行的。这意味着您应该收集数据,直到您检测到行尾字符。执行此操作时,解析缓冲区的内容,然后将其清除。
答案 1 :(得分:1)
正如unwind指出的那样,你不能将数据作为字符串数据直接从管道中处理,并期望事情顺利进行。
您真正需要做的是为数据传输定义协议并编写可以发送和接收该协议的内容。
但是,它并不一定非常复杂。例如,您可能会执行以下操作:前4个字节表示要发送的数据的长度,然后是数据。当您读取4个字节+前4个字节的数据值时,您将对该数据与已知的一组预期值进行比较。如果要使用字符串比较函数,则该数据的一部分可能包含空终止符。您也可以选择使用memcmp()来执行测试,而不使用null终止。
有很多不同的方式来发送数据,虽然这可能感觉有点过分,但你必须小心,不要假设当你打一个电话来阅读时你总能得到你期望的所有数据。在上面的示例中,您将继续调用它,直到您获得预期的数据量,可能会缓冲它直到您拥有所有内容,然后检查它是什么。