c - 从多个管道读取内容,C

标签 c sorting io pipe

我有一个程序,我需要读取几个管道的内容,比较单词,打印最小的单词,从该管道(并且仅该管道)获取一个新单词,再次比较,直到所有管道都为空。

我有几个问题:

1:出于某种原因,我只能从一个管道读取数据。当试图从其他人那里读取时,它一直没有给我任何东西,即使我将管道设置为其他任何管道,它也只适用于该管道。

基本上,我无法让 sortOutput 在需要时切换到其他管道。

2:出于某种原因,我似乎无法检测到数组元素何时为空,因此它将“”与单词进行比较,而“”始终较低。

据我所知,发生的事情是将 sortOutput 设置为最后一个管道,然后它继续从该管道而不是其他管道读取,或者如果被迫通过循环从其他管道读取则什么也没有.我不确定为什么,但是如果我将 sortOutput 显式设置为另一个管道(没有循环,全局声明),它将很好地读取任何其他管道中的所有单词。我认为它正在将 sortOutput 切换到导致问题的循环中的其他管道。奇怪的是,在设置初始单词数组时,将 sortOutput 切换到其他管道工作得很好。请注意,我必须使用 fgets,对此我别无选择。

这是抑制器的代码,我已经在我认为问题发生的地方发表了评论:

//Suppressor - Reads one word from each pipe, compares, prints largest.  Gets next word from that one pipe, compares, prints largest.  
//Suppressor deletes duplicate words
//Reads from pipefds_two[count*2] position
char* words[numChildren];
int index, cont=1;
char* smallest; 
int smallestIndex;
int checker;
int duplicateCount = 0;
int kindex;
char* temptwo;
int length;
int nullCount = 0;
int counter = 0;
FILE* sortOutput;

for(kindex = 0; kindex < numChildren; kindex++){ //Initializes array with beginning values
    sortOutput = fdopen(pipefds_two[kindex*2], "r");
    fgets(buffer, PIPE_BUF, sortOutput);
    words[kindex] = strdup(buffer);
    //fflush(sortOutput);
    close(pipefds_two[(kindex*2)+1]);
}
while(counter < 13){ //This is where it prints out lowest values each "round", gets new words, and gets rid of duplicates
    printf("\nCurrent words in array (0, 1, 2): %s %s %s", words[0], words[1], words[2]);
    for(index = 0; index < numChildren; index++){
        if(words[index] != NULL){ //Searches for first value in array that's not null to be "lowest" value
            smallest = words[index];
            smallestIndex = index;
            printf("Found first non-null word: %s", smallest);
            break;
        }
    }
    printf("Suppressor WHILE \n");
    nullCount = 0;
    printf("smallest word assigned: %s ", smallest);
    printf("smallest index %d\n", smallestIndex);
    for(index = 0; index < numChildren; index++){ //need to loop through each pipe and pull a word, THEN compare them all!
    printf("Suppressor FOR (index: %d word:%s)", index, words[index]);
        if(words[index] == NULL){ //Fills in a NULL gap in the array with a new word from the corresponding pipe
            bzero(buffer, PIPE_BUF);
            sortOutput = fdopen(pipefds_two[index*2], "r"); //THIS IS PROBLEM!  Here, or around here!
            fgets(buffer, PIPE_BUF, sortOutput);
            words[index] = strdup(buffer);
            //fflush(sortOutput);
            printf("the word which replaces a NULL: %s", buffer);
        }
    }
    for(index = 0; index < numChildren; index++){ //COMPARE ALL VALUES NOW THAT IT IS POPULATED
    printf("compare FOR loop index: %d\n", index);
        if((index != numChildren) && (words[index] != NULL) && (index != smallestIndex)){
            printf("IF statement, (current arrayWord: %s)(smallest: %s)", words[index], smallest);
            checker = strcmp(smallest, words[index]); 
            //printf("checker\n");
            if(checker > 0){
                smallest = words[index];
                smallestIndex = index;
                printf("New smallest assigned: %s New Smallest Index: %d\n", smallest, smallestIndex);
            }else if(checker == 0){
                printf("Same word\n");
                words[index] = NULL;
                duplicateCount++;
            }else{
                printf("ArrayWord is larger, smallest staying the same\n");
            }

        } if(index == numChildren-1){ //reached the end of the list
            printf("The smallest this round is: %s", smallest);
            words[smallestIndex] = NULL;
        }
    }
    for(index = 0; index < numChildren; index++){ //Check for removed words!
    printf("Checking if entries are null in array: index %d\n", index);
        if(words[index] == NULL){
            nullCount++;
            printf("words at index null num: %d\n", nullCount);
        }
    }
    //check to see if everything is null
    counter++;
}

我知道 while 循环只设置为计数到 13,但是当我运行它时它不是无限循环并且可以看到发生了什么。

先谢谢大家了!

最佳答案

问题是您多次fdopen管道。第一次fdopen 管道并调用fgets 时,它会将管道的全部内容(或至少不止一行)吸入 FILE 的内部缓冲区,然后给你第一行。下次你 fdopen 管道时,你将丢失所有吸入第一个 FILE 缓冲区的数据,你已经忘记了,因为你忘记了为第一个 fdopen 调用返回的 sortOutput 的值。

你需要做的是让 sortOutput 成为一个 FILE * 的数组,然后在你的管道中循环一次,在每个管道上调用 fdopen 并且将所有生成的 FILE * 存储在数组中。然后,稍后当您想要从管道中读取时,您可以从 sortOutput[index] 中读取,而不是再次调用 fdopen

另外,你说你想阅读(和比较)单词,但你实际上是在阅读(和比较)行——包括他们结束的换行符。只要您的输入行每行一个单词并且没有其他空格或标点符号,就可以正常工作。

您还需要检查每个 fgets 的返回值是否存在 EOF 并进行适当处理。

关于c - 从多个管道读取内容,C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15120076/

相关文章:

c - 如何使用C中的指针将十六进制转换为二进制

c - 从 C 程序读取串行数据部分工作

javascript - 如何使用 javascript 对字母数字列表进行排序

javascript - 按优先选择排序的更高效的方式

java - 需要帮助在java中将数据写入csv文件

Java I/O 到 .txt 文件

c - 写入/dev/mem 失败,地址错误

c - 用于传递多维数组的函数声明

regex - 根据正则表达式对 Mongodb find() 输出进行排序

c - 结构返回类型解释