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

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

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

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

Q&A

4回答

3335閲覧

目的の単語を数えるプログラム

yuto1123581321

総合スコア16

C

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

1グッド

2クリップ

投稿2018/10/16 17:27

編集2018/10/16 23:25

プログラミング初心者です.
大学の課題で任意のテキストファイルの単語数をカウントすると同時にプログラム実行時に入力した単語の個数を出力させよ.というものが出されました.
ここでの単語の定義は空白文字のみを区切りとしたものとします.
ファイルを開き文字配列に格納する操作は習っていないので与えられているので,それ以外を作っています.初心者故にまとめて考えてもわからないのでとりあえずまず1行(ここではBUF)で考えてみて,全単語数と探したい単語数を表示するプログラムを考えています.色々調べながらやってとりあえず下記のものを作ってみたのですが実行時にセグメンテーションフォルトと表示され単語の入力のみで停止してしまします.何が原因であるかわかりやすく教えていただけるとありがたいです.また今回はポインタを習ってからの演習のため,ポインタは必ず用いなければなりません.

とりあえず自分の中のイメージではBUFの先頭を*bufとしてwhile文を使って1文字目から調べていき,if分岐を使って空白でないなら別途用意した文字配列woodにそのまま先頭から入れ,空白ならば(else if内)全単語数を1増やし,その中のif文でstrcmpを使い文字列woodが探したい文字列searchに等しければ目的の単語数を1増やし,最後に切り出すための配列woodを再利用するためにi=0とmemsetを使い初期化しています.

まだ用語などはあまりわからないのでできるだけわかりやすく教えてくれるとありがたいです
お願いします

C

1{ 2 char BUF[5120] = "this is a pen and pen pen"; 3 char *buffer = BUF; 4 char kensaku[20]; 5 char *p_kensaku = kensaku; 6 printf("探す英単語を入力して下さい\n"); 7 fgets(kensaku,sizeof(kensaku),stdin); 8 char wood[20] ; //切り出し用 9 char *p_wood = wood; 10 int i ,j = 0; //カウント変数 11 int search = 0; //目的の単語数 12 int count = 0; //全単語数 13 while(j < sizeof(BUF)) { 14 if(*(buffer + j) != ' ') { 15 wood[i] = *(buffer + j); 16 i++; 17 j++; 18 } else if(*(buffer + j) ==' ') { 19 wood[i] = '\0'; 20 count = count +1; 21 if(strcmp(p_kensaku,p_wood) == 0 ) { 22 search = search + 1; 23 } 24 memset(wood,'\0',20); 25 j++; 26 i=0; 27 } 28 } 29 printf("全単語数:%d\目的の単語数:%d",count,search); 30 31}```ここに言語を入力 32コード
DrqYuto👍を押しています

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

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

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

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

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

y_waiwai

2018/10/16 22:32

このままではコードが見づらいので、質門を編集して、<code>ボタン、’’’の枠の中にコードを貼り付けてください
guest

回答4

0

これだと、BUFの文字列の最後にブランク(' ')がないと正確にカウントされないのでは?

投稿2018/10/17 01:04

miyakichi

総合スコア297

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

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

0

とりあえず、セグメンテーションフォルトは、回避するようにしました。
この原因は、
while(j < sizeof(BUF)) {
のsizeofにあります。sizeof(BUF)の値は、5120になります。これは、あなたの期待した数値ではないでしょう。strlen(BUF)としてください。
int i ,j = 0; //カウント変数

int i=0 ,j = 0; //カウント変数
としてください。(iが0で初期化されていません)
これでもまだ問題が残っていますが、あとは自分で考えてください。
もう一点、バグではないですが、慣習的に、BUFは使用しません。全てが大文字の変数は使わないほうが良いです。すべてが大文字の変数は、(慣習的にですが)定数を定義する場合に使用します。
BUFは、bufのほうが良いでしょう。

C

1#include <stdio.h> 2#include <string.h> 3#include <ctype.h> 4int main(void) 5{ 6 char BUF[5120] = "this is a pen and pen pen"; 7 char *buffer = BUF; 8 char kensaku[20]; 9 char *p_kensaku = kensaku; 10 printf("探す英単語を入力して下さい\n"); 11 fgets(kensaku,sizeof(kensaku),stdin); 12 char wood[20] ; //切り出し用 13 char *p_wood = wood; 14 int i=0 ,j = 0; //カウント変数 //MOD 15 int search = 0; //目的の単語数 16 int count = 0; //全単語数 17 //while(j < sizeof(BUF)) { 18 while(j < strlen(BUF)) { //MOD 19 if(*(buffer + j) != ' ') { 20 wood[i] = *(buffer + j); 21 i++; 22 j++; 23 } else if(*(buffer + j) ==' ') { 24 wood[i] = '\0'; 25 count = count +1; 26 if(strcmp(p_kensaku,p_wood) == 0 ) { 27 search = search + 1; 28 } 29 memset(wood,'\0',20); 30 j++; 31 i=0; 32 } 33 } 34 printf("全単語数:%d\n目的の単語数:%d",count,search); 35 36}

投稿2018/10/16 23:55

tatsu99

総合スコア5438

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

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

ttyp03

2018/10/17 00:00

sizeof(BUF)はセグメンテーションフォルトの原因ではないのでは? 少なくとも5120バイトの領域は確保されているので、あらぬところを参照しているわけではないですし。 strlen(BUF)にするのは正しいと思います。
tatsu99

2018/10/17 00:07

iが初期化されていないのが第1番目に考えられる要因ですが、 strlen(BUF)以降の領域は不定なので、 if(*(buffer + j) != ' ') { wood[i] = *(buffer + j); i++; j++; が成立し、wood[i] = *(buffer + j);が20バイトを超えて、woodの領域を破壊する可能性があります。
tatsu99

2018/10/17 00:10

ああ、すみません。woodの領域が破壊された場合、誤動作の原因にはなりますが、セグメンテーションフォールトになるとは限りませんね。訂正します。
guest

0

全く読んでいませんが、確保されたメモリ以外の場所にアクセスしています。
ループ条件を見直してください。
またメモリがちゃんと確保されているかどうかも確認してください。

それと、目的のプログラムを作るのにコード量はこんなに多くならないと思います。strtok という関数を調べてください。
同様に、標準関数には一通り目を通して、どのようなことができるかはざっと把握してください。

投稿2018/10/16 23:46

Zuishin

総合スコア28660

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

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

yuto1123581321

2018/10/16 23:51

ループ条件を見直してみます。 strtokという関数があるのは言われたのですが今回は使用禁止と指示があったので使えません。書き忘れていました。すみません。 回答ありがとうございます
Zuishin

2018/10/17 00:16

strtok は比較的簡単に実装できるので作ってみるのも手ですね。 すべて main 内で済ますのはよくありません。なるべく小さな機能で汎用に使える関数をたくさん作るのが良いです。 今回は単語の長さが 20 以上になるものはありませんが、i も無制限だし、wood をはみ出さないかどうかも気になります。 ここはどうでしょう? memset(wood,'\0',20); はみ出していませんか? 調べてみてください。
guest

0

詳しくは見ていませんが、

c

1int i ,j = 0; //カウント変数

ここの部分、ijを0で初期化しているつもりかもしれませんが、初期化されるのはjのみです。
iは不定値になるのでwood[i] = ~のところでエラーになっている可能性があります。

投稿2018/10/16 23:45

ttyp03

総合スコア16998

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

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

yuto1123581321

2018/10/16 23:50

iをいじったら全単語数の方は正しく表示されました! ありがとうございます
ttyp03

2018/10/17 00:02

tatsu99さん回答の、strlen(BUF)に変えるとだいたい動くのではないかと思います。 無駄なところなどはいくつかありますが。。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問