C 管道()不';linux不能很好地工作
我正试着用管道通讯做一个程序。这就是我要做的:用户发送正整数。如果用户发送负数,则通信结束。父进程打印最大数和最小数。这就是我所尝试的:C 管道()不';linux不能很好地工作,c,linux,pipe,C,Linux,Pipe,我正试着用管道通讯做一个程序。这就是我要做的:用户发送正整数。如果用户发送负数,则通信结束。父进程打印最大数和最小数。这就是我所尝试的: #include <unistd.h> #include <stdio.h> main(){ int pfd[2]; int buff[200]; pipe(pfd); if(fork()==0){ close(pfd[0]); int n; printf("Give a number: "); scanf("
#include <unistd.h>
#include <stdio.h>
main(){
int pfd[2];
int buff[200];
pipe(pfd);
if(fork()==0){
close(pfd[0]);
int n;
printf("Give a number: ");
scanf("%d",&n);
while(n >=0 ){
write(pfd[1],&n,1);
printf("Give a number: ");
scanf("%d",&n);
}
exit(0);
}
else{
close(pfd[1]);
read(pfd[0],buff,sizeof(buff));
printf("The parent read %d:",*buff);
wait(0);
}
}
#包括
#包括
main(){
int-pfd[2];
智力增益[200];
管道(pfd);
如果(fork()==0){
关闭(pfd[0]);
int n;
printf(“给出一个数字:”);
scanf(“%d”和“&n”);
而(n>=0){
写入(pfd[1],&n,1);
printf(“给出一个数字:”);
scanf(“%d”和“&n”);
}
出口(0);
}
否则{
关闭(pfd[1]);
读取(pfd[0],buff,sizeof(buff));
printf(“父级读取%d:,*buff”);
等待(0);
}
}
这
printf(“父项读取%d:,*buff”)代码>只打印我给出的第一个数字。有人能更好地解释我该做什么吗?如何打印所有的缓冲区?我在缓冲区中只写了一个数字,就这样吗?如何找到最大值和最小值?我很困惑(这可能是因为*buff
是一个整数,但您编写了多个整数
如果要打印发送的所有整数,则需要知道传输了多少,然后在循环中打印它们
您也有一个问题,因为您只发送整数的一个字节(通常是四个字节)
write(pfd[1], &n, sizeof(n));
我相信您不明白
函数(如scanf
和fprintf
)与原始I/O系统调用(如和write(2)
)不同(实际上printf
和fprintf
可以调用write(2)
,您可以用fflush
强制它们这样做)
我不明白您希望在管道上使用的协议是什么。似乎您希望发送原始字节(然后限制为0-255)。还是希望以ASCII格式发送每个数字,每行一个
也许您可以在父进程中执行(假设协议是文本的,ASCII数字,每行一个)
FILE* wp = fdopen(pfd[1],"w");
if (!wp) { perror("fdopen wp"); exit(EXIT_FAILURE); };
int num = -1;
do {
num = 0;
printf("Enter a number:\n");
fflush(NULL);
if (scanf(" %d", &num)<=0) break;
fprintf (wp, "%d\n", num);
} while (num>=0 && !feof(stdin));
fclose(wp);
FILE*wp=fdopen(pfd[1],“w”);
如果(!wp){perror(“fdopen wp”);退出(exit_FAILURE);};
int num=-1;
做{
num=0;
printf(“输入一个数字:\n”);
fflush(空);
如果(scanf(“%d”,&num)=0&&!feof(stdin));
fclose(wp);
在孩子的过程中
FILE* rp = fdopen(pfd[0], "r");
if (!rp) { perror("fdopen rp"); exit(EXIT_FAILURE); };
while (!feof(rp)) {
int rnum = -1;
fflush(NULL);
if (fscanf(" %d", &rnum)<=0) break;
printf ("parent has read %d\n", rnum);
};
FILE*rp=fdopen(pfd[0],“r”);
如果(!rp){perror(“fdopen rp”);退出(exit_FAILURE);};
而(!feof(rp)){
int rnum=-1;
fflush(空);
如果(fscanf(“%d”和&rnum)#包括
#包括
main(){
int-pfd[2];
智力增益[200];
管道(pfd);
如果(fork()==0){
关闭(pfd[0]);
int n;
printf(“给出一个数字:”);
scanf(“%d”和“&n”);
而(n>=0){
printf(“给出一个数字:”);
scanf(“%d”和“&n”);
写入(pfd[1],&n,sizeof(int));
}
出口(0);
}
否则{
关闭(pfd[1]);
/*环路*/
读取(pfd[0],buff,199);
printf(“父级读取%d:,buff”);
/*环路*/
等待(空);
}
}
这个
只写入一个字节。您需要:
write(pfd[1],&n, sizeof n);
这将读取管道缓冲区中可用的任何内容
read(pfd[0],buff,sizeof(buff));
它会一直阻塞,直到有东西要读取,然后返回它实际读取的字节数。可能的顺序是:
child writes your first number (probably 4 bytes)
parent reads the first number
parent executes the wait() sys call
you type in the second number (assume its negative)
child writes the second number
child exits
parent exits
您的父级需要继续读取,直到达到预期的所有数字或达到文件结尾(由读取返回0表示)。类似于:
int bytesRead;
while ((bytesRead = read(pfd[0], buff, sizeof buff)) > 0)
{
// Do whatever it is you want to do with the bytes
}
if (bytesRead == -1)
{
// report the error
}
请注意,从理论上讲,您甚至可能无法一次性读取int的所有四个字节,尽管我认为,在实际使用管道时,这种情况不会发生。这是一种方法,我认为您只需进行很少的修改就可以做到这一点。
请注意,buff
不再是数组,我们在打印数字时将管道本身用作临时存储
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int pfd[2];
int buff;
int max,min;
pipe(pfd);
if(fork()==0){
close(pfd[0]);
int n;
printf("Give a number: ");
scanf("%d",&n);
while(n >=0 ){
write(pfd[1],&n,sizeof(n));
printf("Give a number: ");
scanf("%d",&n);
}
exit(0);
}
else {
close(pfd[1]);
printf("The parent read ");
if (read(pfd[0],&buff,sizeof(int))) {
max = buff;
min = buff;
printf("%d",buff);
}
while (read(pfd[0],&buff,sizeof(int))) {
if (buff > max)
max = buff;
else if (buff < min)
min = buff;
printf("%d:",buff);
}
printf("\n");
printf("The maximum value is: %d.\n The minimum value is: %d.\n",max,min);
wait(NULL);
}
}
#包括
#包括
#包括
内部主(空)
{
int-pfd[2];
int buff;
int max,min;
管道(pfd);
如果(fork()==0){
关闭(pfd[0]);
int n;
printf(“给出一个数字:”);
scanf(“%d”和“&n”);
而(n>=0){
写入(pfd[1],&n,sizeof(n));
printf(“给出一个数字:”);
scanf(“%d”和“&n”);
}
出口(0);
}
否则{
关闭(pfd[1]);
printf(“母读”);
if(读取(pfd[0],&buff,sizeof(int))){
最大值=浅黄色;
最小=浅黄色;
printf(“%d”,浅黄色);
}
while(读取(pfd[0],&buff,sizeof(int))){
如果(增益>最大值)
最大值=浅黄色;
否则如果(buff
您需要调用fflush(NULL)
…您可以使用fdopen
(或者popen
)@BasileStarynkevitch在哪里?fflush做什么?为了正确性/可移植性,写调用应该是write(pfd[1],&n,sizeof(n))
。但是,它不会改变您看到的行为。fflush的作用是什么?
-在linux终端中键入:man fflush并按enter键,您可以看到它的作用does@MoldovanRazvan是的,因为buff
是一个数组,而您想要打印一个整数。正如我在回答中所述,您需要在循环中打印。这就是原因。我如果要发送数字1,则需要发送4个字节。因此,它应该是读写(数组[0],&n,1),而不是写(数组[0],&n,4)。在管道的另一端,您需要将4个字节读入int,然后才能获得正确的数字。如果发送ascii,则需要使用无符号字符,然后在调用write时只发送1个字节。在另一端,您转换为字符,然后将获得ascii数。您还需要知道要读取多少,否则将无法读取I don’我不知道什么时候停止阅读,你将阻止等待信息
int bytesRead;
while ((bytesRead = read(pfd[0], buff, sizeof buff)) > 0)
{
// Do whatever it is you want to do with the bytes
}
if (bytesRead == -1)
{
// report the error
}
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int pfd[2];
int buff;
int max,min;
pipe(pfd);
if(fork()==0){
close(pfd[0]);
int n;
printf("Give a number: ");
scanf("%d",&n);
while(n >=0 ){
write(pfd[1],&n,sizeof(n));
printf("Give a number: ");
scanf("%d",&n);
}
exit(0);
}
else {
close(pfd[1]);
printf("The parent read ");
if (read(pfd[0],&buff,sizeof(int))) {
max = buff;
min = buff;
printf("%d",buff);
}
while (read(pfd[0],&buff,sizeof(int))) {
if (buff > max)
max = buff;
else if (buff < min)
min = buff;
printf("%d:",buff);
}
printf("\n");
printf("The maximum value is: %d.\n The minimum value is: %d.\n",max,min);
wait(NULL);
}
}