目标是为文件中的每个单词创建子进程,并让子进程打印该单词。该文件只有以下五个单词,每个单独一行:
Aachen
Biscay
Capri
Dino
Ellis
问题在于,当我尝试打印到文件时,我会得到一个打印两次的文字。
Aachen
Ellis
Biscay
Capri
Ellis
Dino
这是代码。这似乎很直接,但我无法弄清楚为什么我会得到额外的词。
int main (int argc, char *argv[])
{
char word[50];
int i;
pid_t p;
while (fscanf(stdin, "%s", word) != EOF) {
i = 0;
while (i < sizeof(word)) {
if (word[i] < 'A' || word[i] > 'z') {
word[i] = '\0';
break;
}
i++;
}
p = fork();
if (p != 0)
continue;
break;
}
fprintf(stdout, "%s\n", word);
return 0;
}
我按如下方式运行程序:
$ ./printwords< words2.txt&gt; out.txt
答案 0 :(得分:1)
父亲也在最后打印最后一个字。试试这个,而不是在循环之后打印:
if (p == 0) {
fprintf(stdout, "%s\n", word);
}
else {
continue;
}
答案 1 :(得分:0)
当您使用%s时,Scanf会自动为字符串添加空终结符,因此您可以从代码中删除整个部分:
i = 0;
while (i < sizeof(word))
{
if (word[i] < 'A' || word[i] > 'z')
{
word[i] = '\0';
break;
}
i++;
}
这是我发现有效的解决方案。
#include <stdio.h>
#include <unistd.h>
int main (int argc, char *argv[])
{
char word[50];
int i;
pid_t p;
while (fscanf(stdin, "%s", word) != EOF)
{
p = fork();
if (p != 0)
break; //this will allow the parent process to exit the loop
fprintf(stdout, "%s\n", word);
fflush(stdout);
}
return 0;
}
在再次分叉之前必须刷新输出缓冲区。如果在输出缓冲区刷新之前进行fork,则子进程也将继承该输出缓冲区,这将导致重复。
答案 2 :(得分:0)
// remove pid_t p; attribution in the beginning then:
pid_t = fork();
if( pid_t == 0){
// here we're a child process. put your worker code here
}
else if (pid_t < 0){
printf("Fork failed!");
exit(1);
}
else { // here we're parent process
}