用popen创建的C进程不';t打印它';s输出
作为家庭作业,我必须解决以下问题:用popen创建两个进程。父进程将从stdin行中读取最多30个字符,并将该行中的数字提供给第一个子进程,将该行中的字母提供给第二个子进程,这将把它们转换为大写。然后,两个进程都会将这些内容打印到父进程的标准输出。 所以基本上我想要类似于运行“tee”命令的东西。读一行,写一些输出,然后重复,直到ctrl-d 以下是我的尝试:用popen创建的C进程不';t打印它';s输出,c,popen,C,Popen,作为家庭作业,我必须解决以下问题:用popen创建两个进程。父进程将从stdin行中读取最多30个字符,并将该行中的数字提供给第一个子进程,将该行中的字母提供给第二个子进程,这将把它们转换为大写。然后,两个进程都会将这些内容打印到父进程的标准输出。 所以基本上我想要类似于运行“tee”命令的东西。读一行,写一些输出,然后重复,直到ctrl-d 以下是我的尝试: #include <stdio.h> #include <ctype.h> int main() {
#include <stdio.h>
#include <ctype.h>
int main() {
FILE *digits, *letters;
char string[31];
if ((digits = popen("tee", "w")) == NULL) {
perror("can't create pipe for digits");
return 1;
}
if ((letters = popen("tr a-z A-Z", "w")) == NULL) {
perror("can't create pipe for letters");
return 1;
}
while(!feof(stdin)) {
fgets(string, 31, stdin);
for (char* c = string; *c != '\0'; c++)
if (isdigit(*c))
fputc(*c, digits);
else if (isalpha(*c))
fputc(*c, letters);
fputc('\n', digits);
fputc('\n', letters);
}
pclose(digits);
pclose(letters);
return 0;
}
#包括
#包括
int main(){
文件*数字,*字母;
字符串[31];
如果((数字=popen(“tee”,“w”))==NULL){
perror(“无法为数字创建管道”);
返回1;
}
如果((字母=popen(“tr a-z a-z”,“w”))==NULL){
perror(“无法为字母创建管道”);
返回1;
}
而(!feof(stdin)){
fgets(字符串,31,标准输入);
对于(char*c=string;*c!='\0';c++)
如果(isdigit(*c))
fputc(*c,数字);
否则,如果(isalpha(*c))
fputc(*c,字母);
fputc('\n',位);
fputc(“\n”,字母);
}
pclose(数字);
pclose(信件);
返回0;
}
但在我写了一行并按enter键之后,程序希望再次输入,而不打印任何内容。按下ctrl-d键后,它将在末尾打印所有输出。我不明白为什么。它正确地读取该行,然后将正确的字符提供给每个子级,然后是新行。为什么这些流程不立即打印输出?调用pclose时是否运行实际命令?因为我找不到关于这个的任何信息。此外,将“\n”写入孩子的stdin是否与按enter键相同?更奇怪的是,每个孩子输出的最后一行被打印了两次
例如,以下是我希望它的工作方式:
(input)
1a2b3c
(output)
123
ABC
(input)
4d5e6f
(output)
456
DEF
(ctrl-d)
(输入)
1a2b3c
(产出)
123
基础知识
(输入)
4d5e6f
(产出)
456
DEF
(ctrl-d)
但我明白了:
(input)
1a2b3c
(input)
4d5e6f
(ctrl-d)
(output)
123
456
456
ABC
DEF
DEF
(输入)
1a2b3c
(输入)
4d5e6f
(ctrl-d)
(产出)
123
456
456
基础知识
DEF
DEF
如果缓冲区正在等待打印,您可能需要调用fflush(stdout)将内容从缓冲区中取出。@possum实际上我需要做的是fflush数字和字母,这是我正在写入的两个流。它们没有立即执行的原因是,我给它们的输入仍然在缓冲区中,并且没有实际写入它们。现在一切正常抱歉,是的,那些是溪流。很高兴你明白了!您应该检查
fgets
的返回值。检查文件的结尾!feof(stdin)
发生在fgets
之前,因此它没有达到您期望的效果。请注意,如果缓冲区正在等待打印,您可能需要调用fflush(stdout)将内容从缓冲区中取出。@possum实际上,我需要做的是fflush数字和字母,这是我正在写入的两个流。它们没有立即执行的原因是,我给它们的输入仍然在缓冲区中,并且没有实际写入它们。现在一切正常抱歉,是的,那些是溪流。很高兴你明白了!您应该检查fgets
的返回值。检查文件的结尾!feof(stdin)
发生在fgets
之前,因此它没有达到您期望的效果。请看