我试图通过管道使用bc来获得char表达式的答案。 我想首先在pipe1中编写表达式,bc将读取并在pipe2中写入答案。为此,我正在改变输入和输出。如果我不使用char []并将表达式放在write:
中,这确实有效write(pipe1[1], "20*5\n", sizeof("20*5\n")-1) != sizeof("20*5\n")-1)
但如果我宣布一个标签,我会不断收到错误:
(standard_in) 2: illegal character: ^@
有时它是1而不是2
我做错了什么?如果有人能解释我,谢谢你。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
char resultat[5];
int pipe1[2];
int pipe2[2];
pipe(pipe1);
pipe(pipe2);
int resultat_fork = fork();
if (resultat_fork == -1)
{
exit(EXIT_FAILURE);
}
char* expression = "20*5\n";
if (resultat_fork != 0)
{
//printf("I am the parent\n");
close(pipe1[0]);
close(pipe2[1]);
if (write(pipe1[1], expression, sizeof(expression)) != sizeof(expression))
fprintf(stderr, "write to child failed\n");
int nbytes = read(pipe2[0], resultat, sizeof(resultat));
if (nbytes <= 0)
fprintf(stderr, "read from child failed\n");
else
printf("resultat: %.*s\n", nbytes, resultat);
close(pipe1[1]);
close(pipe2[0]);
}
else
{
printf("I am the child\n");
close(pipe1[1]);
close(pipe2[0]);
dup2(pipe1[0], 0);
dup2(pipe2[1], 1);
close(pipe1[0]); /* More closes! */
close(pipe2[1]); /* More closes! */
execlp("bc", "bc", NULL);
fprintf(stderr, "Failed to execute bc\n");
exit(EXIT_FAILURE);
}
return 0;
}
答案 0 :(得分:1)
^@
是空字符,即'\0'
。这会建议您在将其写入bc
时超出字符串的结尾。问题出在这里:
sizeof(expression)
expression
不是一个数组,它是一个char
指针,指向字符串"20*5\n"
的第一个字符,如果你在64位机器上,它的大小是8.要获取要发送的字符串的长度,请改用strlen(expression)
。
您需要做的另一件事与您的问题无关,在父进程中,您已经阅读了答案,wait以完成子进程。否则,你将留下一个僵尸。
答案 1 :(得分:0)
这是错误的
if (write(pipe1[1], expression, sizeof(expression)) != sizeof(expression))
您正在使用sizeof
运算符expression
char*
,如果您的系统是32位,则会生成4
,其大小为代码中的任何指针变量。
您需要使用strlen(expression)
代替sizeof
。
正如答案中所指出的,如果父进程有多个子进程,则需要等待子进程完成执行并终止。理想情况下,您还应检查wait
的返回值,它为您提供有关子进程如何终止的更多背景信息。