2013-02-27 118 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