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);
    }
}