質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

11362閲覧

C言語 単語数カウント

zoon555

総合スコア17

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2019/04/24 11:58

c言語でファイルを読み込んだ後に、単語数をカウントするコードを書いています。
Today=1
we=2
というように表示されるプログラムを目指しているのですが、コンパイルをすると下にある画像のように
Today=2097185
we=2097186
となってしまいます。どうしたら正しく表示されるようになりますか?
また余裕がありましたら大文字、小文字を区別せずカウント(the=Theと認識しカウント)する方法やコンマやピリオドを単語から離れさせてカウント(today.→today)する方法も教えていただきたいです。

以下作成した文書ファイルの引用、ソースコード、コマンドプロンプトの画像です。

Today we had a nice warm day. The day before yesterday was pretty cloudy. I forgot the name of the girl whom we met in the restaurant today.

#include <stdio.h> #include <string.h> #define LIST_MAX 1000 #define SENTENCE_MAX 1000 int main(){ int i,j,count[LIST_MAX]; char ch, Slist[LIST_MAX][SENTENCE_MAX],Wlist[SENTENCE_MAX]; FILE *fp; fp = fopen("test.txt","r"); for(i=0; i<LIST_MAX; i++){ Wlist[i]=0; //0から開始 sentence[i]=0? } j=0; do{ ch =fgetc(fp); //条件に当てはまったら一文字ずつすすむ while(ch == ' ' || ch == '\n' || ch == '\t') ch=fgetc(fp); i=0; Wlist[i]=ch; while((ch=fgetc(fp)) !=' ' && ch!='\n' && ch!='\t' && ch!=EOF){ Wlist[++i]=ch; } Wlist[++i]='\0'; for(i=0; i<j; i++){ if(strcmp(Wlist,Slist[i])==0){ count[i]++; break; } } if(i==j){ j++; strcpy(Slist[j-1],Wlist); count[j-1]++; } }while((ch != EOF)); for(i=0; i<j ;i++){ /*リストが埋まったところまで(空のところまで)*/ printf("%s = %d\n",Slist[i],count[i]); } fclose(fp); }

イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

count[LIST_MAX]をゼロで初期化して下さい。

あと、
for(i=0; i<LIST_MAX; i++){は、SENTENCE_MAXの間違い。たまたま同じ値ですが
chint
EOFの処理がおかしい
というのがありますが、初心者ががんばってよくここまで書けたと思います。

小文字を区別せずカウント(the=Theと認識しカウント)する

案1:読み込んだ時点で、英字はtolower()で小文字に統一する(大文字に統一でもいいですが)
案2:比較時に、strcmp()でなくstrcasecmp()を使う

コンマやピリオドを単語から離れさせてカウント

空白文字のように読み飛ばせば良いのでは?

投稿2019/04/24 12:39

otn

総合スコア84423

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zoon555

2019/04/24 13:52

回答ありがとうございます! ご指摘頂いた箇所修正してみます
guest

0

ベストアンサー

滅茶苦茶な値が表示されるときは、領域が初期化されていない場合が多いです。

C

int i,j,count[LIST_MAX];

count[LIST_MAX] = {0} と書いておきましょう。
第一要素だけ明示的に書いておけば、残りの領域も0で初期化してくれます。

大文字、小文字を区別せずカウント(the=Theと認識しカウント)する方法やコンマやピリオドを単語から離れさせてカウント(today.→today)する方法

単語数を数える処理に移る前に一周舐めて、
大文字の変換・記号の除去を前以て済ませておくと楽かと思います。

投稿2019/04/24 12:07

編集2019/04/24 12:08
LouiS0616

総合スコア35658

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zoon555

2019/04/24 12:22

1回目のforのところでWlistを初期化していたのですが、countを初期化するように直したら上手くいきました! 初期化を気づかせてくださりありがとうございました。
guest

0

単語の中にいる状態と中にいない状態さえわかればカウントできるのでは?
記号などの区切り文字と英数字の判断は、ispunct()isalanum()で判定できます。
あと、1文字ずつ読んでもいいですが、fgets()で、一行まるごと持ってくれば処理が楽ですよ。(改行の判定も出来ます)

投稿2019/04/24 12:19

cateye

総合スコア6851

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cateye

2019/04/24 12:51 編集

>大文字、小文字を区別せずカウント・・・に関しては、読み込んだ単語をすべて大文字(小文字にして)カウントすればいいと思います。アルファベットの判定は、isalpha() あと、大文字(小文字)にするには、toupper()(tolower())を使います。
cateye

2019/04/24 12:49

なんかしつこいのかなぁw・・・今回は関係なさそうだけど・・・ 単語とは何か? たとえば、2019というのは、ただの数字?それとも西暦?・・・決めごとでいいのだと思いますが、年号なら単語に入るのかも?
zoon555

2019/04/24 13:54

詳しい回答ありがとうございます!まだまだ勉強中なので沢山指摘していただいて助かります!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問