我正在编写一个实现管道的小程序,就像它们在shell中工作一样。 即:
ls -hal | sort | grep p | wc
它工作正常,在一行上的次要问题,当CMD_NO = n时,CMD_NO的比较大不起作用,但是i!=(CMD_NO-1)。我试图弄清楚为什么在这种特殊情况下(该行在代码中被命名为TROUBLED LINE)这些语句不等效。非常感谢。
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#define READ_END 0
#define WRITE_END 1
#define CMDS_NO 5
int main (int argc, char **argv)
{
pid_t pid;
int new_fds[2];
int old_fds[2];
char *array[CMDS_NO];
char *param[CMDS_NO];
array[0]="ls";
array[1]="sort";
array[2]="grep";
array[3]="grep";
array[4]="wc";
param[0]="-hal";
param[1]=NULL;
param[2]="p";
param[3]="out";
param[4]=NULL;
for (int i=0; i<CMDS_NO; i++) {
if (i<CMDS_NO) //if there is a next command
pipe(new_fds);
pid=fork();
if (pid==0) { //if child
if (i!=0) { //if there is ap revoius commmand
dup2(old_fds[0], 0);
close(old_fds[0]);
close(old_fds[1]);
}
if (i!=(CMDS_NO-1)) { //TROUBLED LINE i<CMDS_NO does not work,
//if there is a next command
close(new_fds[0]);
dup2(new_fds[1],1);
close(new_fds[1]);
}
execlp(array[i], array[i], param[i], NULL);
} else {
if (i!=0) { //if there is a previous command
close(old_fds[0]);
close(old_fds[1]);
}
if (i<CMDS_NO) { //if there is a next command
old_fds[0] = new_fds[0];
old_fds[1] = new_fds[1];
}
}
}
if (CMDS_NO>1) {
close(old_fds[0]);
close(old_fds[1]);
}
while (1) { //wait for child processes to end
wait(NULL);
if(errno== ECHILD) {
printf("all children ended\n");
break;
}
}
return 0;
}
答案 0 :(得分:1)
条件i<CMDS_NO
始终为真,因为i
从0到CMDS_NO-1
。我想你的意思是把你的条件写成i<CMDS_NO-1
。当然,i!=CMDS_NO-1
同样有效。
请注意,这会影响您拥有if (i<CMDS_NO)
的其他几个地方;这些也应该是if (i<CMDS_NO-1)
。
答案 1 :(得分:1)
这是正常的。
for (int i=0; i<CMDS_NO; i++) {
这意味着“只要i
小于CMDS_NO
”就会循环播放。一旦i == CMDS_NO
循环停止;因此,在循环内,最高i
将达到CMDS_NO - 1
。
PS:CMDS_NO
是一个非常糟糕的变量名称,例如将其称为MAX_COMMANDS