構造体が入ったソート

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
うりぼー

構造体が入ったソート

#1

投稿記事 by うりぼー » 10年前

入力された英語の文章中に含まれる英単語(英文字の列)の出現回数を数え, 多いものから順に表示する.をC言語で構造体を用いて実装せよ.

という課題が出たのですが、これだとワーニングが出て実行するとセグメンテーションフォルトになります。
ポインタが苦手なのでそこだと思うのですが、解決法が分かりません。
よろしくおねがいします。

コード:

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#define WORDLEN 50   //単語の長さ
#define MAXWORD 10000  //単語の量

struct wd {   //構造体
  char *str;     //単語
  int count;     //出現回数
};

typedef struct wd WORD;  //構造体の名前

WORD word[MAXWORD];     //構造体の配列の枠の数

int n_word;             //大域変数(英単語の数)

void init_word();      //プロトタイプ宣言(n_word初期化)

int add_word(char *);  //英単語の出現回数

char *getword(char *, int);  //大文字の英単語を文字配列に読み込む

void insertion_sort(WORD **, int);


int main()
{

    char w[WORDLEN];
    int i;

    init_word();    //n_word初期化

    while (getword(w, WORDLEN) != NULL) {   //文字配列がNULLでないとき
      i = add_word(w);    //
	if (i < 0) {
	    fprintf(stderr, "Too many words\n");
	    exit(1);
	}
	word[i].count++;   //出現回数をカウント
    }

     
 

insertion_sort(&word, n_word);


    for (i = 0; i < n_word; i++) {   //出力
	printf("%d %s\n", word[i].count, word[i].str);
    }

    return 0;
}

void init_word()     //n_word初期化
{
    n_word = 0;
}


int add_word(char *w)
{
    int i;
    char *s;

    for (i = 0; i < n_word; i++) {

      if (strcmp(w, word[i].str) == 0)  //等しいとき
	    return i;
    }

    i = n_word;

    if (i >= MAXWORD)   //英単語が多すぎるとき

	return -1;

    s = (char *)malloc(strlen(w) + 1);   //文字列sと同じ内容の新しい文字配列領域を作成

    if (s == NULL)  //エラー

	return -1;

    strcpy(s, w);   //wを文字配列sにコピー

    word[i].str = s;

    word[i].count = 0;

    n_word++;

    return i;

}

char *getword(char *w, int n)
{
    int c;
    int i = 0;

    if (n <= 0 || feof(stdin))    //nが負または入力の終端ならば

	return NULL;

    c = getchar();    //一字読み込み

    while (c != EOF && ! isalpha(c)) {    //入力の終わりで無い、かつ英文字で無いとき
      c = getchar();       //読み飛ばす
    }

    if (c == EOF)  //入力の終わりのとき

	return NULL;

    while (isalpha(c)) {     //英文字のとき
	if (i < n - 1)

	  w[i++] = toupper(c);   //大文字に変換して配列wに代入

	c = getchar();

    }

    if (i < n)  

      w[i++] = '\0';    //NULL

    return w;

}


void insertion_sort(WORD *a[], int n)
{
    int i, j;
    WORD *p;

    for (i = 1; i < n; i++) {
	p = a[i];
	for (j = i; j > 0 && p->count < a[j-1]->count; j--)
	  a[j] = a[j-1];
	a[j] = p;
    }
}
ワーニング
ex2-1.c:50:16: warning: incompatible pointer types passing 'WORD (*)[10000]' to
parameter of type 'WORD **' (aka 'struct wd **')
[-Wincompatible-pointer-types]
insertion_sort(&word, n_word);
^~~~~
ex2-1.c:27:28: note: passing argument to parameter here
void insertion_sort(WORD **, int);
^
1 warning generated.

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 構造体が入ったソート

#2

投稿記事 by みけCAT » 10年前

wordはWORD型の配列なのに、insertion_sort関数ではWORD*型の「配列」を処理するようになっているのが問題だと思います。
50行目を

コード:

insertion_sort(word, n_word);
とし、insertion_word関数を

コード:

void insertion_sort(WORD a[], int n)
{
    int i, j;
    WORD p;

    for (i = 1; i < n; i++) {
	p = a[i];
	for (j = i; j > 0 && p.count < a[j-1].count; j--)
	  a[j] = a[j-1];
	a[j] = p;
    }
}
としてみてください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

うりぼー

Re: 構造体が入ったソート

#3

投稿記事 by うりぼー » 10年前

みけCATさん、それでやってみたらいけました!
本当にありがとうございました!

閉鎖

“C言語何でも質問掲示板” へ戻る