首页 > 解决方案 > 将浮点数转换为字符串并通过命名管道从 C 代码发送到 Python

问题描述

我想使用命名管道将浮点值从 C 代码发送到 Python 代码。我正在将接收到的值打印到 Python 端的终端中,但是除了值本身之外,还会显示乱码。

管道开口:

void Init_FIFO(void)
{
    // FIFO file path
    char * bldc_fifo = "/tmp/bldc_fifo";

    // Creating the named FIFO -- mkfifo(<pathname>, <permission>)
    mkfifo(bldc_fifo, 0666);

    // Open FIFO to write/read data
    fd_fifo = open(bldc_fifo, O_RDWR | O_NONBLOCK);
    //fd_fifo = open(bldc_fifo, O_WRONLY | O_RDONLY | O_NONBLOCK);
}

对于浮点数到字符串的转换,我使用 sprintf,代码如下,

void SendDataOverFifo(float angle)
{
    char str[64];
    unsigned char writeBuffer[] = "Hello!";

    Init_FIFO();

    sprintf(str, "%f\n", angle);
    write(fd_fifo, str, sizeof(str));
    //write(fd_fifo, writeBuffer, sizeof(writeBuffer));
    close(fd_fifo);
}

然后为了在 Python 端接收代码,我使用这个

#!/usr/bin/python

import os
import errno
import time

FIFO = '/tmp/bldc_fifo'

try:
    os.mkfifo(FIFO)
except OSError as oe: 
    if oe.errno != errno.EEXIST:
        raise

print("Opening FIFO...")
with open(FIFO, encoding='utf-8', errors='ignore') as fifo:
    print("FIFO opened")
    while True:
        time.sleep(0.1)
        data = fifo.read()
        print(data)

我得到的输出是这样的

iW ?UOeiEU11.417070

正确的结果应该是:

11.417070

注意:如果我尝试只发送“你好!”,它可以正常工作。

我在这里想念什么?提前致谢。

标签: pythonclinuxnamed-pipes

解决方案


第一个红旗在sprintf通话中;它不知道你的目标缓冲区str有多大,所以如果你不小心可能会溢出。使用单个浮点数和 64 个字节,这一步应该没问题。

但是,您没有存储返回值,所以此时您不知道格式化文本有多大。然后你使用sizeof,它告诉你缓冲区有多大,而不是你刚刚放入了多少数据。您可以使用基于字符串的函数(因为sprintf编写了一个以 nul 结尾的字符串),例如strlen(测量字符串)或fputs(将字符串写入文件)。

一个更简单的快捷方式可能是首先使用fprintf,并且不需要分配单独的缓冲区(它可能使用内置的缓冲区FILE)来存储格式化的字符串。

尽管不一定可移植或安全,write但可以close使用FILE诸如.fprintffdopen


推荐阅读