C 程序在“fork()”和管道中存在问题
Posted
技术标签:
【中文标题】C 程序在“fork()”和管道中存在问题【英文标题】:C program having issues inside "fork()" and pipes 【发布时间】:2021-04-12 01:36:27 【问题描述】:您好,我是 C 语言中亲子交流的初学者。我正在尝试使用 C 编程构建一个计算器,它只会从文件中读取数据,使用 fork()
和 pipe
进行一些计算,然后确定输出。我能够从文件中读取运算符以及文件中的数字,但在 if(fork() == 0)
条件内使用 dup
时遇到问题。 close(1);
以上的一切都在工作,但之后的一切都不起作用。我使用输入流 0 读取第一个参数,使用流 3 读取第二个参数,并使用标准输出流 1 进行输出。我知道在那之后我必须设置加法、减法、乘法和除法的条件,然后在我弄清楚之后使用execl
来计算计算,但我无法弄清楚为什么我会遇到这个问题,任何帮助都会不胜感激谢谢!这是下面的代码和输入文件。为了程序,我们需要将文件名作为参数传递。例如./calc data.txt
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#define MAXLEN 1000
int fds[100][2];
char operators[100];
int main(int argc, char *argv[])
char line[MAXLEN], *temp;
FILE *dataFile = fopen(argv[1], "r");
//read the first line - it contains the configuration
fgets(line, MAXLEN, dataFile);
// sample content for line: a + b - c
strtok(line, " \n"); //skip the symbol representing variable/parameter
int count=0;
while (temp = strtok(NULL, " \n"))
operators[count] = temp[0];
printf("operator: %c\n", operators[count]);
count++;
strtok(NULL, " \n"); //skip the symbol representing variable/parameter
int x[count+1];
int num = 0;
while (fscanf(dataFile, "%d", &x[num]) > 0)
printf("%d\n", x[num]);
num++;
for(int h=0; h<count*2+1; h++)
pipe(fds[h]);
printf("%d \n",h);
printf("Count: %d\n", count);
for(int i = 0; i < count; i++)
//printf("%c\n", operators[i]);
if (fork() == 0)
//printf("Value of operators: %c\n",operators[i]);
close(0);
dup(fds[2*i][0]);
close(3);
dup(fds[2*i+1][0]);
//printf("After close(3)\n");
if(operators[i] == '+')
printf("Add \n");
close(1);
printf("After close(0) \n");
dup(fds[2*i+2][1]);
printf("Value of operators: %c\n", operators[i]);
if(operators[i] == '+')
printf("Add %n");
`
`
【问题讨论】:
您为此使用fork
有什么特别的原因吗?您正在为输入中的每个运算符创建一个流程。我不确定这是否真的是你想要做的。
有人告诉我使用 fork
OT:关于:FILE *dataFile = fopen(argv[1], "r");
在没有首先检查argc
以确保用户实际输入了预期的命令行参数之前,永远不要访问argv[0]
以外的地方
OT:请不要使用 while (temp = strtok(NULL, " \n"))
分配总是导致true
这不是你想要的。建议:while ( (temp = strtok(NULL, " \n"))) )
(注意额外的括号)将检查 temp
的内容是否为 != NULL
【参考方案1】:
文件描述符 1 引用 stdout
。如果您关闭它,您对 printf
的调用将失败,因为它会尝试打印到已关闭的流。
【讨论】:
那我该怎么做呢?因为我还必须检查运算符才能计算。我该怎么做? 你能做什么?您可以完全按照使用close(1)
的方式关闭文件描述符1。但文件描述符 1 指的是 stdout
- 标准输出流,即您的终端。当你关闭它时,你不能再向它打印输出了。
如何确保close(1)
之后的 if 条件有效?因为最后这就是我需要的,我也可以在里面使用execl
,如果条件它会起作用吗?
@eliesmith 条件应该可以正常工作。问题是当条件为真时您调用的printf
。它出错是因为它无法打印到您刚刚关闭的流中。请阅读一些对标准 I/O 以及进程和分叉的介绍,因为从代码来看,您似乎对如何使用它没有正确的想法。
你能帮助mw吗?我必须为所有数学运算符这样做以上是关于C 程序在“fork()”和管道中存在问题的主要内容,如果未能解决你的问题,请参考以下文章
Unix上用C程序实现pipe管道命令“ | “(pipe,fork,dup2,close,execl,重定向)