構造体の問題

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

構造体の問題

#1

投稿記事 by as_468 » 8年前

リダイレクト機能を使って任意のテキストファイルを読み込み、すべての異なる英単語を取得し、それらを出現頻度順(降順)に並び替えるプログラムがわかりません。

条件として、必ず構造体を使うこと、英文字は大文字と小文字を分けること、FILE構造体を使ったファイル処理は使ってはいけないこと、があります。

as_468

Re: 構造体の問題

#2

投稿記事 by as_468 » 8年前

as_468 さんが書きました:リダイレクト機能を使って任意のテキストファイルを読み込み、すべての異なる英単語を取得し、それらを出現頻度順(降順)に並び替えるプログラムがわかりません。

条件として、必ず構造体を使うこと、英文字は大文字と小文字を分けること、FILE構造体を使ったファイル処理は使ってはいけないこと、があります。
今、下のようなプログラムまで書いたのですが、エラーは出ませんがSegmentation faultになってしまいます。

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

#define MAX_WORD 2048

/*構造体*/
typedef struct {
int cnt[MAX_WORD];
char read[MAX_WORD][MAX_WORD];
}English;

/*新しい単語をセットする*/
void set_word(int total, int i, int cnt_word[], char *EngWord[])
{
int j;

for(j = 0; j <= total - 2; j++) {
if (strcmp(EngWord, EngWord[j]) == 0) {
cnt_word[j]++; /*既出の単語だった場合、単語のカウントをインクリメント*/
i--;
total--;
}
}
}

/*カウントした要素を降順で並び替え*/
void bsort(int total, int cword[], char *EngWord[])
{
int i, j;

for (i = 0; i < total; i++) {
for (j = 1; j < total + 1; j++) {
if (cword > cword[j]) {
int temp1 = cword;
char *temp2 = EngWord;
cword = cword[j];
EngWord = EngWord[j];
cword[j] = temp1;
EngWord[j] = temp2;
}
}
}
}

void print_result(int total, int cnt_word[], char *EngWord[])
{
int i;

for(i = 1; i <= total; i++){
printf("%s: %5d times\n", EngWord, cnt_word);
}
}
int main(void)
{
English word;

int c;
int i = 0;
int j = 0;
int f = 1;
int total = 0;
char *EngWord[MAX_WORD];

while ((c = getchar()) != EOF) {
if (isalnum(c)) {
f = 0;
word.read[j] = c;
j++;
} else {
if (f == 0) {
f = 1;
word.read[j] = '\0';
EngWord[i] = &word.read[i][0];
word.cnt[i] = 1;
i++;
j = 0;
total++;
if (total >= 2) {
set_word(total, i, word.cnt ,EngWord);
}
}
}
}

bsort(total, word.cnt, EngWord);

print_result(total, word.cnt, EngWord);

return 0;
}

metaphor

Re: 構造体の問題

#3

投稿記事 by metaphor » 8年前

"Segmentation fault"のエラー自体は単純なもので二次配列の形で大変大きな領域を確保しようとした場合に発生します。
#define MAX_WORD 100 //2048
で直ると思うけど、構造体自体の設計が間違っていると思われます。(構造体配列の動的領域確保mallocにするといいと思います)

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

Re: 構造体の問題

#4

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

ソースコードを提示する際は、BBCodeが有効な(無効にしない)状態でBBCodeのcodeタグで囲んでいただけると、見やすくてありがたいです。
metaphor さんが書きました:"Segmentation fault"のエラー自体は単純なもので二次配列の形で大変大きな領域を確保しようとした場合に発生します。
スタックオーバーフローによるSegmentation Faultの場合、二次配列かどうかは関係なく大きすぎる領域を(通常スタック上に確保される)自動変数として確保しようとすると発生します。
as_468 さんが書きました:今、下のようなプログラムまで書いたのですが、エラーは出ませんがSegmentation faultになってしまいます。
デバッガなどで確かめてはいませんが、bsort関数やprint_result関数で初期化されていないEngWord[total]の値を使っているように見えます。
未初期化の自動変数の値は不定であり、それを用いた計算をすると未定義動作になります。
特に、デタラメなポインタをprintfの%sに渡すと、デタラメな場所を読み込もうとしてSegmentation Faultを起こすかもしれません。

また、set_word関数で仮引数のiやtotalの値を変更していますが、この変更によってmain関数のローカル変数のiやtotalの値が変わることはありません。
呼び出した関数に呼び出し元のデータを書き換えてもらいたい場合は、書き換えてもらいたいデータのポインタを渡す必要があります。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

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

Re: 構造体の問題

#5

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

as_468 さんが書きました:条件として、必ず構造体を使うこと

コード:

typedef struct {
    int count;
    char word[MAX_WORD];
} word_t;

word_t wordList[MAX_WORD];
みたいな感じにするとよさそうだと思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

as_468

Re: 構造体の問題

#6

投稿記事 by as_468 » 8年前

metaphor さんが書きました:"Segmentation fault"のエラー自体は単純なもので二次配列の形で大変大きな領域を確保しようとした場合に発生します。
#define MAX_WORD 100 //2048
で直ると思うけど、構造体自体の設計が間違っていると思われます。(構造体配列の動的領域確保mallocにするといいと思います)
やってみます!

閉鎖

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