Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Pipes和fork-scanf仅读取一个字符_C_Linux_Fork_Pipe_Scanf - Fatal编程技术网

Pipes和fork-scanf仅读取一个字符

Pipes和fork-scanf仅读取一个字符,c,linux,fork,pipe,scanf,C,Linux,Fork,Pipe,Scanf,我的任务是编写3个用管道连接在一起的进程。第一个应该从用户处读取输入,第二个应该从第一个处读取并使字母大写,第三个应该从第二个处读取并打印结果。问题是scanf只读取第一个按下的字符,然后程序结束。我做错了什么?我试着发送硬编码字符串,但效果很好 #include <unistd.h> #include <stdio.h> #include <ctype.h> #define ODCZYT 0 #define ZAPIS 1 int main(){

我的任务是编写3个用管道连接在一起的进程。第一个应该从用户处读取输入,第二个应该从第一个处读取并使字母大写,第三个应该从第二个处读取并打印结果。问题是scanf只读取第一个按下的字符,然后程序结束。我做错了什么?我试着发送硬编码字符串,但效果很好

#include <unistd.h>
#include <stdio.h>
#include <ctype.h>
#define ODCZYT 0
#define ZAPIS 1

int main(){
        char readbuffer[80];
        char tempbuffer[80];
        char printbuffer[80];
        int i=0;

        int potok[2];
        int potok2[2];
        pid_t pid_A, pid_B, pid_C;

        pipe( potok );
        pipe( potok2);
        puts( "fork" );
        if(!(pid_A = fork()) )
        {

                puts("Podaj string:");
                close(potok[ODCZYT]);
                close(potok2[ODCZYT]);
                close(potok2[ZAPIS]);
                scanf( "%s", readbuffer )
                write(potok[ZAPIS],readbuffer, sizeof(readbuffer));    
                close(potok[ZAPIS]);
        }
        if(!(pid_B = fork()) )
        {
                close( potok[ZAPIS] );
                close(potok2[ODCZYT]);
                read( potok[ODCZYT], tempbuffer, sizeof(tempbuffer));
                close(potok[ODCZYT]);
                while(tempbuffer[i]){
                        tempbuffer[i]=toupper(tempbuffer[i]);          
                        i++;                   
                }
                write(potok2[ZAPIS],tempbuffer, sizeof(tempbuffer));
                close(potok2[ZAPIS]);
        }
        if( !(pid_C = fork()) ) {

                close(potok[ODCZYT]);
                close(potok[ZAPIS]);
                close(potok2[ZAPIS]);
                read( potok2[ODCZYT], printbuffer, sizeof(printbuffer));
                puts(printbuffer);
                close(potok2[ODCZYT]);

        }
        return 0;
}
#包括
#包括
#包括
#定义ODCZYT 0
#定义ZAPIS 1
int main(){
字符读取缓冲区[80];
字符缓冲区[80];
字符打印缓冲区[80];
int i=0;
int-potok[2];
int potok2[2];
pid_t pid_A、pid_B、pid_C;
管道(potok);
管道(potok2);
出售(“叉子”);
如果(!(pid_A=fork())
{
puts(“Podaj字符串:”);
关闭(potok[ODCZYT]);
关闭(potok2[ODCZYT]);
关闭(potok2[ZAPIS]);
scanf(“%s”,readbuffer)
写入(potok[ZAPIS],readbuffer,sizeof(readbuffer));
关闭(potok[ZAPIS]);
}
如果(!(pid_B=fork())
{
关闭(potok[ZAPIS]);
关闭(potok2[ODCZYT]);
读取(potok[ODCZYT],tempbuffer,sizeof(tempbuffer));
关闭(potok[ODCZYT]);
while(tempbuffer[i]){
tempbuffer[i]=toupper(tempbuffer[i]);
i++;
}
写入(potok2[ZAPIS],tempbuffer,sizeof(tempbuffer));
关闭(potok2[ZAPIS]);
}
如果(!(pid_C=fork()){
关闭(potok[ODCZYT]);
关闭(potok[ZAPIS]);
关闭(potok2[ZAPIS]);
读取(potok2[ODCZYT],printbuffer,sizeof(printbuffer));
puts(打印缓冲区);
关闭(potok2[ODCZYT]);
}
返回0;
}

问题代码可能比预期做得更多。它不是创建3个进程,而是创建7个进程,不包括
main()
进程,实际上总共是8个进程

线程[main()]确实创建了线程[A]、[B]和[C]

线程[A]在第一个
if
块中执行工作,然后继续创建线程[B1]和[C1]

线程[B]在第二个
if
块中执行工作,然后继续并创建线程[C2]

线程[B1]在第二个
if
块中执行工作,然后继续并创建线程[C3]

回顾一下,总线程包括[main()]、[A]、[B]、[C]、[B1]、[C1]、[C2]、[C3]

这不是问题描述所指出的


要修复代码,请在每个“if”块的底部放置一个
return(0)
语句,这将导致每个线程只执行其“if”块中的任务


还有一个小小的修正。。。更改:

scanf( "%s", readbuffer )
致:

然后运行程序:

> ./test < test.txt
(当然,为了引用
waitpid()
,您必须添加相应的.h文件。)


固定代码可在以下位置找到:
}读()和写()不能保证返回您请求的所有字节。检查read()和write()调用的返回值,查看实际读写了多少个字符。您可能需要循环以获取所有这些。另外,我没有运行您的代码段,但您没有对父进程执行任何操作。您需要在每个条件结束时退出父项,以防止它运行下一节,这可能会产生不良后果

您有多个小错误,下面回答了其中的一小部分。首先,你必须学会检查你的返回代码。如果你什么时候做,很多事情会变得更清楚。
uppercase
> ./test < test.txt
   waitpid(pid_C, NULL, 0);

   return(0);