1

いくつかのパイプの内容を読み取り、単語を比較し、最小の単語を印刷し、そのパイプ(およびそのパイプのみ)から新しい単語を取得し、すべてのパイプが空になるまで再度比較する必要があるプログラムがあります。

私にはいくつかの問題があります:

1:どういうわけか、私は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にカウントするように設定されているだけですが、それを実行すると無限ループではなく、何が起こっているかを確認できます。

よろしくお願いします!

4

1 に答える 1

2

問題はfdopen、パイプを複数回使用していることです。初めてfdopenパイプして を呼び出すとfgets、パイプの内容全体 (または少なくとも 1 行よりも多く) がFILEの内部バッファーに吸い込まれ、最初の行が表示されます。次にパイプを実行すると、最初の呼び出しで返されたの値を忘れてしまったのでfdopen、最初の のバッファに吸い込まれたすべてのデータが失われます。FILEsortOutputfdopen

あなたがする必要があるのはsortOutput、配列を作成しFILE *てから、パイプを一度ループして、各パイプで呼び出しfdopen、結果のすべてのFILE *s を配列に格納することです。その後、後でパイプから読み取りたい場合は、再度sortOutput[index]呼び出す代わりに読み取りますfdopen

また、単語を読みたい (そして比較したい) と言っていますが、実際には行を読み (そして比較) しているので、最後の改行も含まれています。入力行に 1 行に 1 つの単語があり、他のスペースや句読点がない限り、これは問題なく機能します。

また、EOF の各 fgets の戻り値を確認し、適切に処理する必要があります。

于 2013-02-27T19:10:41.917 に答える