本人在学习的时候,完成进程通过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)); // 将数据写入命令行
}
这两种方法的其中一种去修改,就不会出现乱码的问题了