2013-02-27 88 views
1

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

我有几个问题:

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

基本上,我不能得到sortOutput切换到其他管道,当我想要它。

2:出于某种原因,我似乎无法检测到数组元素为空,因此它比较“”字,而“”总是较低。

据我所知,发生了什么是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,但就是这样它不是一个无限循环,当我运行它,可以看到发生了什么。

谢谢大家提前!

回答

2

问题是你多次管道fdopen。当您第一次fdopen一个管道,并呼吁fgets,它会吸管(或至少多行多很多)到FILE的内部缓冲区中的所有内容,然后给你的第一道防线。你fdopen管,你将失去所有的数据下一次吸入到第一FILE的缓冲区,你已经忘了,你已经忘记了这是第一个fdopen调用返回的sortOutput值。

你需要做的是让sortOutput通过你的水管ONCE呼吁各管fdopen和存储阵列中的所有结果FILE * S的FILE *数组,然后循环。然后,后来当你想从管道读,你读从sortOutput[index]而不是再次调用fdopen

而且,你说你想阅读(比较)的话,但你实际上读取(和比较)线 - 包括他们的结束换行符。只要你的输入行每行有一个单词,没有其他空格或标点符号,这将工作正常。

你还需要检查每个与fgets为EOF的返回值,并适当地处理它。

+0

哦。我的。神。我还没有实施,但这样做非常感觉! – FeralShadow 2013-02-27 19:39:28

+0

你。先生。 你值得拥有至少30块饼干。至少!!!!111oneone 你已经让我的一周! – FeralShadow 2013-02-27 22:20:19