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

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

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

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

Q&A

3回答

1881閲覧

Segmentation fault: 11 の原因・解決策を知りたい

chiyabon18

総合スコア12

C

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

0グッド

0クリップ

投稿2019/04/23 07:27

###ファイルから単語を読み取ってそれぞれの単語が何個あるかカウントするプログラム

発生している問題・エラーメッセージ

Segmentation fault: 11

↓このときそれぞれの配列の前に&をつけるようwarningが出てくるが参考書やネットで調べても&がいるとは書いていない strcmp(newWord[i], WORDlist[i]) strcpy(newWord[i], WORDlist[i])

C言語

1//Display characert frequents in a file(test.txt) 2#include <stdio.h> 3#include <strings.h> 4#define LIST_MAX 1000 5#define SENTENCE_MAX 1000 6int main(){ 7 int i, WORDcount [LIST_MAX]; 8 char ch, WORDlist [LIST_MAX], newWord[SENTENCE_MAX]; 9 FILE *fp; //ファイルポインタの作成 10 fp = fopen("text.txt", "r"); 11 12 for(i=0; i<LIST_MAX; i++){ 13 WORDcount[i]=0;//0からスタート 14 WORDlist[i]=0;//default character 15 } 16 17 do{ 18 ch=fgetc(fp);//ファイルから一文字読み取る 19 for(i=0; (( ch!=32 ) && ( ch!=EOF )); i++){ 20 if(strcmp(newWord[i], WORDlist[i]) == 0) 21 //スペースがくるまで 22 break; 23 } 24 if(WORDcount[i]>0){ //WORDリストに取ってきた文字があった場合 25 ++i; 26 }else{ 27 ++i; //0→1 strcpy 28 strcpy(WORDlist[i], newWord[i]);//WORDlistに登録 文字列なので =で代入できない 29 } 30 }while((ch != EOF)); 31 32 for(i=0; (( ch!='\0' ) && ( ch!=EOF )); i++){ //文字列の最後に含まれている\0 33 printf("%c = %d\n", WORDlist[i], WORDcount[i]); 34 } 35 fclose(fp); 36} 37 38

試したこと

最初に用意しておく配列の長さが短いのかと思い要素数を増やした

ターミナルで実行

ファイルからfgetcでスペースがくるまで(ASCIIコードで32)文字を読み取り、スペースがきたら読み取った単語(newWordという配列にある)がWORDlistという配列にすでに含まれているかをstrcmpで比べる。
あった→WORDcountのiの値に1を足す
なかった→WORDcountのiを0から1にする
newWordの配列にある読み取った単語をWORDlistの配列にstrcpyを用いてコピーする

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

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

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

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

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

guest

回答3

0

C言語のstrcmp関数は

#include <string.h> int strcmp( const char *str1 , const char *str2 );

と定義されています。
2つの引数は文字列へのポインタでなければなりません。("char *str1" というのが、str1が文字(char)へのポインタであることを表している事はご存知ですよね)

「前に&をつけるようwarningが出てくる」というのは、下記のコードでは両方の引数が文字(文字の配列であるnewWordのi番目と、文字の配列であるWORDlistのi番目)になっているので
『ポインタが入るべきところが文字になってますよ、(前に & をつけて)文字へのポインタにすべきじゃないですか』という親切なアドバイスを含んだ警告が出されたのです。

strcmp(newWord[i], WORDlist[i])

そのプログラムでメモリがどのように確保されて実行されるのかは分かりませんが、文字(例えば"a")をメモリのアドレス0x61としてアクセスしたら未使用領域などに達してSegmentation faultが起きるのは必然です。

「参考書やネットで調べても&がいるとは書いていない」というのは、C言語の理解が足りないからです。
C言語の教科書を丁寧に読み直すことをお勧めします。

投稿2019/04/23 08:11

coco_bauer

総合スコア6915

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

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

0

参考書やネットで調べても&がいるとは書いていない。

それは文字列の名前だけ([]が付かない)の比較じゃないでしょうか?
※わたしも探してみましたが文字列を途中からコピーしたり比較したりする例は見つかりませんでした。

strcmp()やstrcpy()は文字列(終端が'\0')を対象とする関数です。
文字の比較ではありません。したがって
strcmp(newWord[i], WORDlist[i]) は、は文字をアドレスとして渡していることになります。
エラーにならなければ、何が起こってもしょうがない状況です。
「追記」
そのままコンパイルすると以下のワーニングが出ます。
・・・説明の出来ないエラーやワーニングは潰しましょう。
参考:エラーメッセージの読み方と対処, 検索や質問の原則

text

1usr ~/Project/test % cc t4.c 2t4.c:18:8: warning: implicit conversion loses integer precision: 'int' to 'char' 3 [-Wimplicit-int-conversion] 4 ch=fgetc(fp);//ファイルから一文字読み取る 5 ~^~~~~~~~~ 6t4.c:20:10: warning: implicitly declaring library function 'strcmp' with type 'int 7 (const char *, const char *)' [-Wimplicit-function-declaration] 8 if(strcmp(newWord[i], WORDlist[i]) == 0) 9 ^ 10t4.c:20:10: note: include the header <string.h> or explicitly provide a declaration for 'strcmp' 11t4.c:20:17: warning: incompatible integer to pointer conversion passing 'char' to parameter of 12 type 'const char *'; take the address with & [-Wint-conversion] 13 if(strcmp(newWord[i], WORDlist[i]) == 0) 14 ^~~~~~~~~~ 15 & 16t4.c:20:29: warning: incompatible integer to pointer conversion passing 'char' to parameter of 17 type 'const char *'; take the address with & [-Wint-conversion] 18 if(strcmp(newWord[i], WORDlist[i]) == 0) 19 ^~~~~~~~~~~ 20 & 21t4.c:28:7: warning: implicitly declaring library function 'strcpy' with type 22 'char *(char *, const char *)' [-Wimplicit-function-declaration] 23 strcpy(WORDlist[i], newWord[i]);//WORDlistに登録 文字列なので =で代入できない 24 ^ 25t4.c:28:7: note: include the header <string.h> or explicitly provide a declaration for 'strcpy' 26t4.c:28:14: warning: incompatible integer to pointer conversion passing 'char' to parameter of 27 type 'char *'; take the address with & [-Wint-conversion] 28 strcpy(WORDlist[i], newWord[i]);//WORDlistに登録 文字列なので =で代入できない 29 ^~~~~~~~~~~ 30 & 31t4.c:28:27: warning: incompatible integer to pointer conversion passing 'char' to parameter of 32 type 'const char *'; take the address with & [-Wint-conversion] 33 strcpy(WORDlist[i], newWord[i]);//WORDlistに登録 文字列なので =で代入できない 34 ^~~~~~~~~~ 35 & 36t4.c:32:15: warning: variable 'ch' used in loop condition not modified in loop body 37 [-Wfor-loop-analysis] 38 for(i=0; (( ch!='\0' ) && ( ch!=EOF )); i++){ //文字列の最後に含まれている\0 39 ^~ ~~ 408 warnings generated. 41usr ~/Project/test % 42

投稿2019/04/23 08:32

編集2019/04/23 09:47
cateye

総合スコア6851

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

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

cateye

2019/04/23 09:56 編集

for(i=0; i<LIST_MAX; i++){ WORDcount[i]=0;//0からスタート WORDlist[i]=0;//default character } ・・・もおかしいです、通常NULL文字は'\0’と書きます。・・・これはダメなのじゃなくて文字を入れてること明確にするためです。 あと、ch=fgetc(fp);のchはintでなければEOFの判定が出来ません。
guest

0

C言語の場合、文字列を入れるのに配列が必要なので、char WORDlist [LIST_MAX]は「1つの文字列」扱いです。なので、WORDlist[i]はそのうちの1文字だけを指すものとなり、文字列を入れるのには適当でありません(警告が出ているのも、そういう理由での型の不一致によるものです)。

どうしてもC言語でやらないといけない事情があるのでなければ、別な言語にすることをおすすめします。

投稿2019/04/23 07:39

maisumakun

総合スコア145183

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問