我是C的新手,因此我对以下行为感到困惑。使用pipe()
和fork()
我正在阅读以下琐碎的ruby程序的输出:
puts "success"
通过调用C:中的读取函数
n = read(fd[0], readbuffer, sizeof(readbuffer));
printf("received: %s", readbuffer);
然而,printf
正在向控制台打印一堆“无法识别的字符”符号(如钻石中的问号)。此外,进行比较,如:
if (strcmp(readbuffer, "success") == 0)
{
/* do something */
}
失败。我做错了什么?
编辑:按要求声明。我不知道忘记了,我在C的第一天。
int fd[2], in;
pid_t pid;
char readbuffer[6];
编辑:
'mu太短'的答案也解决了这个问题。共识似乎是使用memset
是过度的。我是新手C程序员所以我必须相信评论员的意见。然而,这是一个论点和广告,而且太短可能确实更加正确。在任何情况下,我建议阅读这两个答案,因为任何“过度杀伤”可能仍然是如此。
答案 0 :(得分:2)
正如其他人所指出的那样,你的缓冲区不够大,无法保存你正在阅读的文本,而且你不能确保它的空终止。
但是在每次读取之前使用memset()
将整个缓冲区归零是不必要的;你只需要确保在你读过的数据末尾有一个空值(并且当然会使你的缓冲区更大)。
如果您将readbuffer
设置为至少9个字符,请替换:
n = read(fd[0], readbuffer, sizeof(readbuffer));
.. ..用
n = read(fd[0], readbuffer, sizeof(readbuffer) - 1);
readbuffer[n] = '\0';
..然后应该这样做(尽管你应该理想地检查n
是> = 0以确保read()
成功)。指定一个小于读取缓冲区的大小可确保readbuffer[n]
不会溢出(但如果read()
失败则可能会欠载)。
然后你必须在最后处理换行。
这也假定在一次读取调用中读取整个字符串。在这种情况下很可能,但通常在使用read来连接多个读取时,直到你读完了足够的数据。
答案 1 :(得分:1)
正如评论所指出的那样,readbuffer
上没有空终结符,所以它实际上不是C字符串。你可以这样做:
#include <string.h>
/* ... */
memset(readbuffer, 0, sizeof(readbuffer));
n = read(fd[0], readbuffer, sizeof(readbuffer) - 1);
这将为您提供正确的以空字符结尾的字符串。但是,如果您确实需要长度为6的字符串,请将readbuffer
的声明更改为:
char readbuffer[7];
如果您只需要readbuffer
一次,可以说:
char readbuffer[7] = { 0 };
将其初始化为全零。但是,如果您在循环中执行read
,那么您需要在每个memset(readbuffer, 0, sizeof(readbuffer))
之前read
,以确保您不会得到最后一个的剩余数据步骤
C不会自动初始化局部变量,你必须自己动手。
答案 2 :(得分:1)
据我所知,你的行:
puts "success"
将输出(以C语言表示)
success\n\0
我算作9个字符。
您仅将readbuffer
声明为6.之前的答案仅将其提升为7。