1

ファイルに表示される単語(繰り返しなし)とそれらが最初に表示される行のリンクリストを作成しています。難しい部分(行を追跡しながらファイルを解析する)であると思っていたものを終了しましたが、修正方法がわからないという私の方法の1つに問題があると思います。私のコードは2つのファイルにありますが、ドライバーと一緒にコードに問題のあるメソッドのみを含めています。(GDBを使用してみましたが、ファイルが見つからず、実行されないと言われ続けたため、間違って使用していたと思います。)

int main(int argc, char **argv){
file = fopen(argv[1],"r");
/*struct fileIndex *fIndex = NULL;*/ /*put this in header file??*/
fIndex = NULL;
delimiters = " .,;:!-";/*strtok chars to seperate*/
rewind(file);
int buffer = 65;
char str[buffer+1];/*where the lines are being stored*/
char *token, *cp;
int i;
int len;
while((fgets(str, buffer, file))!=NULL){/*inserting lines*/
for(i=0; i<buffer; i++){
    if(str[i]=='\n'){
    str[i]= '\0';
    break;
    }
}
len = strlen(str);
cp = xerox(str);
token = strtok(cp, delimiters);
/*if(token!=NULL)
printf("The word is %s\n", token);*/
    if(!present(fIndex, token)&&(token!=NULL)){
        insert(fIndex, i+1, token);
    }
    while(token!=NULL){
        token = strtok(NULL, delimiters);
        /*if(token!=NULL)
        printf("The word is %s\n", token);*/
        if(!present(fIndex, token)&&(token!=NULL)){
            insert(fIndex, i+1, token);
        }

    }
}
fclose(file);
struct fileIndex *root;
root = fIndex;

while(root != NULL){
printf("The string is %s and on line %d\n", root -> str, root -> lineNum);
root = root -> next;
}


free(fIndex);
free(cp);

return 0;
}







struct fileIndex *insert(struct fileIndex *head, int num, char *insert){
struct fileIndex* newnode = malloc(sizeof(struct fileIndex));
if(newnode==NULL)
exit(1);

newnode -> str = insert;
newnode -> lineNum = num;

newnode -> next = head;
return newnode;
}

編集:私はまた、単語がすでにそこにあるかどうかをチェックするための私の方法に問題があると考えています。単語が挿入され、すべての単語が印刷される場合にのみ印刷される印刷ステートメントを配置します。リストを印刷するための最後の小さなループは印刷されておらず、最初にそこに到達したときにNULLに達し、ループすることはないと思います。

present(struct fileIndex* fIndex, char *findIt){/*finds if word is in structure*/
struct fileIndex* current = fIndex;
while(current!=NULL){
current = current -> next;
if(strcmpigncase(current -> str, findIt)==0){
    return current -> lineNum;
}
}
return 0;
}
4

3 に答える 3

2

挿入関数は新しいリストを返しますが、コードで戻り値を使用していません。

呼び出しは次のようになります。

fIndex = insert(fIndex, i+1, token);

補遺:

また、トークンがNULLかどうかを確認する前に、トークンを使用しています。次のようになります。

if((token!=NULL) && !present(fIndex, token)){
    fIndex = insert(fIndex, i+1, token);
}
于 2012-04-10T01:12:53.363 に答える
2

fopen()が成功したことを常に確認する必要があります。

if(file == NULL) {
printf("Error fopen");
exit(1);
}

fgets()nullターミネータを追加するので、自分でそれを行う必要はありません。

于 2012-04-10T01:18:43.363 に答える
0
file = fopen(argv[1],"r");

fopen()成功したことを確認するのを忘れました。すべてのfopen(3)後に、次のようなコードを続ける必要があります。

if (!file) {
    fprintf(stderr, "unable to open %s\n", argv[1]);
    perror(argv[0]);
    exit(EXIT_FAILURE);
}

終了するよりも適切にエラーを処理できる場合(デフォルトにフォールバックしますか?)、そうすることをお勧めします。

for(i=0; i<buffer; i++){
    if(str[i]=='\n'){
    str[i]= '\0';
    break;
    }

これはかなり醜いです。自分でnullを終了する必要はありませんが、改行を削除する場合は、行番号の改行をカウントしていることも確認する必要があります...

struct fileIndex *root;
root = fIndex;

while(root != NULL){
    printf("The string is %s and on line %d\n", root -> str, root -> lineNum);
    root = root -> next;
}


free(fIndex);
free(cp);

私は実際にfIndex割り当てられたのを見たことがありません-それは単なるポインタであり、あなたNULLは最初にそれを割り当てました。コードのこのセクション全体が固定されているように見え、適切なインデントと周囲のコンテキストがないため、理解するのはほぼ不可能です。このすべてのコードを独自のルーチンに分離し、ハードコードされたテストを使用して徹底的にテストし、より大きなプログラムに接続する前に、完全に機能することを確認する必要があると考えなければなりません。(これは実際には最初の部分にも当てはまります。分離された指示されたテストの恩恵を受けるようです。)

于 2012-04-10T01:20:10.540 に答える