0

次のプログラムは、すべての単語を格納してから、それらを出現回数とともに出力します。
グローバルtypedef宣言:

typedef struct {
    char * word;
    int occ;
}
words;
words *data=NULL;

検索機能に問題があります。次のような関数を返しintます:(max構造体の配列のサイズは常に更新されるため、にEOF達した後に検索関数を呼び出します)。

int search(char *word,int max)
{
    int i;
    for(i=0; i<max; i++)
    {
        if(!strcmp(data[i].word,word)) return i;
    }
    return -1;
}

しかし、私はそのプロトタイプを持つ検索関数を書くことになっていることに気づきました:

struct abc *find(char *word)

そこで、次のコードを作成しました。

struct words *findword(char *word)
{
    struct words *ptr;

    for (ptr = data; ptr != NULL; ptr++) {      /* IS THE STOP CONDITION OK? */
        if (strcmp(word, ptr->word) == 0)
            return ptr;
    }
    return NULL;          

}

そして、コンパイル中に多くのエラーが発生します。

reverse.c:関数'findword'内:

reverse.c:73:警告:互換性のないポインタ型からの割り当て

reverse.c:73:エラー:不明な構造へのポインターの増分

reverse.c:73:エラー:不完全な型へのポインターの算術

reverse.c:74:エラー:不完全な型へのポインターの間接参照

reverse.c:関数'main'内:

reverse.c:171:エラー:'これは'宣言されていません(この関数での最初の使用)

reverse.c:171:エラー:(宣言されていない各識別子は1回だけ報告されます

reverse.c:171:エラー:表示される関数ごとに。)

make:* [reverse.o]エラー1


whichint最初に作成した検索関数の戻り値に割り当てられた変数です。のエラーwhichは簡単に修正できますが、それを置き換える方法がわかりません(ベース検索機能で動作するソリューション):

data[which].occ++;

検索への新しいアプローチで機能するように修正するにはどうすればよいですか?


編集

main()追加した:

int main(int argc, char **argv)
{
    char *word;
    words *temp;
    int c,i,num;
    /*int which;*/
    FILE *infile;

    if(argc!=2) {}      
    if((infile=fopen(argv[1],"r"))==NULL) {}
    num=0;
    while(1)
    {
        c=fgetc(infile);
        if(c==EOF) break;
        if(!isalpha(c)) continue;
        else ungetc(c,infile);
        word=getword(infile);
        word=convert(word);
        /*which=search(word,num);*/ 
        if(findword(word))
        {
            if(!(temp=realloc(data,sizeof(words)*(num+1))))
            {}
            else
                data=temp;
            data[num].word=strdup(word);
            data[num].occ=1;
            num++;
        }
        else
            data[which].occ++;

        free(word);
    }
    sort(num-1);
    for(i=0;i<num;i++)
    {}
    free(data);
    if(fclose(infile))
    {}  
    return 0;
}

私は{}無関係なコードの断片に向けて出発しました。エラー処理。


EDIT2 私が上で求めているものは修正されています。しかし、今はセグメンテーション違反が発生しています。コード全体へのリンクを示します。大きな混乱を招くため、編集済みの投稿には入れたくありません。セグメンテーション違反は73行目と152行目が原因です(strcmpが何らかの理由で機能していません)。完全なコードが理解しやすくなることを願っています。 フルコード

4

3 に答える 3

2
for (ptr = data; ptr != NULL; ptr++) {    
/* IS THE STOP CONDITION OK? */

いいえ。ポインタは増え続けます。そのコードでNULLになる唯一のことは、整数のオーバーフローです。データ領域を0にプリセットした場合、それが何を指しているかを確認し、それがNULLであるかどうかを確認できます。

#define NUM_WORDS 100
data = calloc(NUM_WORDS,sizeof(words));

または

#define NUM_WORDS 100
int bytes = NUM_WORDS * sizeof(words);
data = malloc(bytes);
memset(data,0,bytes);

...。

for (ptr = data; ptr->word != NULL; ptr++) { 

データ領域を0にプリセットしたくない場合は、ループする量を知るために、データ領域に現在保持されている構造体の現在の量を関数に渡す必要があります。

于 2012-09-18T13:00:20.467 に答える
2

問題はfindword関数にあり、すべての行を調べてみましょう

struct words *ptr; 

これはあなたがやろうと思っていることではありません。構造のtypedef定義に使用したので、structもう書く必要はありません。これが、エラーが発生する理由ですreverse.c:73: error: increment of pointer to unknown structure。あなたが欲しいのはただ:

words *ptr;    

次に、ループ:

for(ptr=data; //This is fine, you're assigning your local ptr to the global data. I assume that's something valid

ptr != NULL; //That could OK too... we can loop while ptr is not NULL
ptr++)       //This line makes no sense... 

forループがどのように機能するかをもう一度調べたいと思うかもしれません。要点は、条件に達するまで何かをインクリメントしているということです。ptr ++はあなたが指している場所にも移動するので、あなたはもはやあなたの構造を指していません。

私はあなたmain()が達成しようとしていることを理解するためにあなたの関数を見る必要があります、しかしあなたが従わなければならないプロトタイプに基づいて、私は最も簡単な解決策は次のようなものだと思います:

void main()
{
    // init your vars
    bool more_words_to_add = true;
    words *ptr = NULL;
    int i;

    // populate your array of words
    while(more_words_to_add) {
        for(i = 0; i<max; i++) {
          if(ptr = findword("word"))  //if we find the word
            ptr->occ++;  //increment the number of times we found it
          else {
            //I don't know what you want to do here, it's not clear what your goal is.
            //Add the new word to your array of words and set occ to 1,
            //then increment max because there's one more word in your array?
          }
        }
        //get the next word to fine, or else set more_words_to_add = false to break
    }
}

このタイプのソリューションが目的のソリューションである場合は、findwords関数を非常に単純になるように調整できます。

struct words *findword(char *word)
{
    words *ptr = data;
    if (strcmp(word, ptr->word) == 0)
        return ptr;
    return NULL;
}  

編集:あなたの新しいエラーについては、問題はあなたのメモリ割り当てにあると思います、あなたの構造を使用するこの短い例を見てください:

words *findword(char *word)
{
    words *ptr = data;
    if(strcmp(word, ptr->word) == 0)
      return ptr;
    return NULL;
}

int main(){
    words *ptr;

    data = realloc(data, sizeof(words));
    data->word = "hello";                //DO NOT SKIP THESE LINES
    data->occ = 0;                       //DO NOT SKIP THESE LINES

    if(ptr = findword("hello")) {
      ptr->occ++;
      printf("I found %d %s's\n",ptr->occ, ptr->word);
    }
} 

mike@linux-4puc:~> ./a.out 
I found 1 hello's

ここで、グローバル構造にメモリを割り当てる必要があることがわかります。その後、データを格納してポインタを渡すことができます。

編集2:

あなたのmain()コードはこれを行います:

if((ptr = findword(word)))
{
     //do stuff
}
else
  ptr->occ++;

findword()が失敗するとNULLが返されるため、これは機能しません。したがって、if check ptrがNULLに設定されている場合、elseではNULLを無視しようとしています。(そして、私が実際にあなたのロジックを読んでいないので、これはあなた次第であることに注意してください)単語が見つからない場合にptr-> occを本当にインクリメントしたい場合は、代わりにこれが必要です:

if(findword(word))
{
     ptr = findword(word);
     //do stuff
}
else
  ptr->occ++; //increments the current ptr's occ, no new ptr was assigned.
于 2012-09-18T13:38:16.333 に答える
1

struct wordsあなたのプログラムのようなものはありません。名前のないstruct型と、その型に対するtypedefwordsがあります。使用するstruct wordsか、words一貫して使用します。

その後、交換する必要があります

data[which].occ++;

result->occ++;

ここで、resultは新しい検索関数からの戻り値です。

于 2012-09-18T12:21:20.773 に答える