Linux系统编程--STDOUT_FILENO乱码问题

本人在学习的时候,完成进程通过fifo实现通信问题是遇到一个bug,首先看代码

int main(int argc, char *argv[])
{
    int fd, i;
    char buf[4096];
    fd = open(argv[1], O_WRONLY);
    if (fd == -1)
    {
        perror("open error");
    }
    i = 0;
    while (1)
    {
        sprintf(buf, "hello fifo%d\n", i++);
        write(fd, buf, sizeof(buf));
        sleep(1);
    }
    close(fd);
    return 0;
}

这段代码是从进程中写入数据到fifo管道中

int main(int argc, char *argv[])
{
    int fd, len;
    char buf[4096];
    fd = open(argv[1], O_RDONLY);
    if (fd == -1)
    {
        perror("open error");
    }
    while (1)
    {
        len = read(fd, buf, sizeof(buf));
        write(STDOUT_FILENO, buf, len);
        sleep(3);
    }
    
    return 0;
}

这是从fifo管道中读出数据并且读到屏幕上

运行之后,出现了乱码的情况。。
但是把通过文件描述符STDOUT_FILENO写到屏幕上的write函数这一行

write(STDOUT_FILENO, buf, len);

换成

printf("%s", buf);

就能正常输出了

后面对比了这两个函数得知
printf会自行给读入的字符加上’\0’,转化为字符串,read是通过字节来读入,并且read和这个write都没有往字符后面添加字节的功能,所以系统分不清字符串出现乱码
要修改程序如下

int main(int argc, char *argv[])
{
    int fd, i;
    char buf[4096];
    fd = open(argv[1], O_WRONLY);
    if (fd == -1)
    {
        perror("open error");
    }
    i = 0;
    while (1)
    {
        sprintf(buf, "hello fifo%d\n", i++);
        write(fd, buf, strlen(buf));
        sleep(1);
    }
    close(fd);
    return 0;

这里可以通过把sizeof修改成strlen
在第一个代码片段中,write() 函数基于字符串的长度使用 strlen(buf) 来写入数据。这是因为 sprintf() 函数会将格式化后的字符串存储在 buf 中,其中以 null 字符 ‘\0’ 结尾,因此可以使用 strlen() 来获取正确的字符串长度,而不是使用 sizeof(buf)。

然而,在第二个代码片段中,由于 read() 函数只返回读取的字节数,并不添加 null 字符 ‘\0’ 来标识字符串的结束,导致在使用 write() 函数输出数据时可能会输出一些非法的内容,从而出现乱码。

或者改第二个读出写到屏幕上的程序
把while循环中read出来的数据后面加一个’\0’

 while (1) {
     len = read(fd, buf, sizeof(buf) - 1);  // 从 FIFO 管道读取数据
     buf[len] = '\0';  // 在读取的数据中添加字符串结束符
     write(STDOUT_FILENO, data, strlen(data));  // 将数据写入命令行
 }

这两种方法的其中一种去修改,就不会出现乱码的问题了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值