テキストファイルの読み込みが出来なくて困っています。

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

テキストファイルの読み込みが出来なくて困っています。

#1

投稿記事 by サイクロン » 13年前

テキストファイルの読み込みが出来なくて困っています。
このプログラムはテキストファイルを読み込んで表示するだけのプログラムです。
すべてmain関数に書いていたときはちゃんと動いていたのですが、
関数に分けたら何故か動かなくなってしまいました。

コード:

 
#include <stdio.h>
#define NUM 40

void readf(char**);

int i,f;

int main()
{
	char* genso[NUM];
	readf(genso);
	for(i=0;i<NUM;i++){
        printf("%s\n",genso[i]);
	}
	return 0;
}	
void readf(char** genso)
{
	FILE *fp;
	fp=fopen("genso.txt","r");	//ファイルの読み込み
	while(1){
		fgets(genso[i],NUM,fp);
		if(feof(fp))break;
  	}
	fclose(fp);
	return;
}
コンパイルはできるのですが、
"Segmentation fault (コアダンプ)"
と表示されて処理が止まってしまいます。
OSはUbuntu13.04でコンパイラはgccです。
どこが間違っているか教えてください。
よろしくおねがいします。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: テキストファイルの読み込みが出来なくて困っています。

#2

投稿記事 by softya(ソフト屋) » 13年前

このコードだと元から動いていないのでは無いかと思うのですが。
char* genso[NUM];だとchar *をNUM個定義しているだけなので、ポインタの値が未初期化です。
つまり、そのポインタ値を使う以上はSegmentation fault は必然だと思われます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

サイクロン

Re: テキストファイルの読み込みが出来なくて困っています。

#3

投稿記事 by サイクロン » 13年前

コード:

#include <stdio.h>
#define NUM 40

void readf(char**);

int i,f;

int main()
{
	char genso[NUM];
	char** gensop;
	gensop=&genso;
	readf(gensop);
	for(i=0;i<NUM;i++){
		printf("%s\n",&genso[i]);
	}
	return 0;
}
void readf(char** genso)
{
	FILE *fp;
	fp=fopen("genso.txt","r");	//ファイルの読み込み
	i=0;
	while(1){
		i++;
		fgets(genso[i],NUM,fp);
		if(feof(fp))break;
	}
	printf("%d\n",i);
	fclose(fp);
	return;
}
アドバイスどうりにプログラムを変えてみましたが
また別のエラーが出てしまいました。
"genso.c:12:8: 警告: 互換性のないポインタ型からの代入です [デフォルトで有効]"
配列の変数名だけ書くと
配列の最初のポインタが得られるものだと思っていたのですが
何故かエラーが出てしまいます。
どのようにすればエラーが出なくなるでしょうか?

non
記事: 1097
登録日時: 15年前

Re: テキストファイルの読み込みが出来なくて困っています。

#4

投稿記事 by non » 13年前

これは、課題ですか?
課題なら正確に課題を書いてください。
要するに、動的にメモリを確保しなさいという課題なのかわかりません。
non

box
記事: 2002
登録日時: 15年前

Re: テキストファイルの読み込みが出来なくて困っています。

#5

投稿記事 by box » 13年前

サイクロン さんが書きました: すべてmain関数に書いていたときはちゃんと動いていた
では、そのコードを提示してください。
サイクロン さんが書きました: 関数に分けたら何故か動かなくなってしまいました。
なぜだかわからないけど動かない、ということは、まあないでしょうね。
現象には必ず理由があります。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: テキストファイルの読み込みが出来なくて困っています。

#6

投稿記事 by softya(ソフト屋) » 13年前

想定されているのは、文字列をNUM個の配列に読み込むことではないのでしょうか?
であれば、まずNUM個分の文字列を用意しないといけません。
文字列は文字の配列ですので、文字の配列をNUM個用意すると言うことです。
現状は、char genso[NUM];ですので、NUM個分の文字の配列が有るだけです。【誤字修正】

nonさんの言われている通り課題であれば、問題の詳細をお願いします。
動いていたという関数を分ける前のプログラムも見せてもらったほうが良いかもしれません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

サイクロン

Re: テキストファイルの読み込みが出来なくて困っています。

#7

投稿記事 by サイクロン » 13年前

動いていたプログラムはこんなかんじです。

コード:

#include <stdio.h>
#define NUM 40

int i,f;

int main()
{
	char genso[NUM];
	FILE *fp;
	fp=fopen("genso.txt","r");	//ファイルの読み込み
	while(1){
		fgets(genso,NUM,fp);
		if(feof(fp))break;
		printf("%s",genso);
	}
	fclose(fp);
	return 0;
}
これは課題などではなく、趣味でやっていることです。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: テキストファイルの読み込みが出来なくて困っています。

#8

投稿記事 by softya(ソフト屋) » 13年前

それだと、すでに元のプログラムと想定している動作が変わっています。
そこで質問です。
新しい関数化プログラムでのNUMと元のNUMでは意味は変わっているのでしょうか?
それとも文字列の最大長の意味のままですか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

サイクロン

Re: テキストファイルの読み込みが出来なくて困っています。

#9

投稿記事 by サイクロン » 13年前

一応同じつもりで書いています。
ただ、僕は初心者なので別の意味になっているかもしれません。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: テキストファイルの読み込みが出来なくて困っています。

#10

投稿記事 by softya(ソフト屋) » 13年前

サイクロン さんが書きました:一応同じつもりで書いています。
ただ、僕は初心者なので別の意味になっているかもしれません。
であれば、引数にするときにポインタの扱いを間違っていますし、呼び出し元でも全然違う意味で使っています。
まず元のmainだけのプログラムで、入力のwhileループと出力のprintfループを別のループに分離してみてください。
関数化の前に、それが出来ていないと関数化ができません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

サイクロン

Re: テキストファイルの読み込みが出来なくて困っています。

#11

投稿記事 by サイクロン » 13年前

コード:



#include <stdio.h>
#define NUM 40

int i,f;

int main()
{
	char genso[NUM][100];
	FILE *fp;
	fp=fopen("genso.txt","r");	//ファイルの読み込み
	i=0;
	while(1){
		fgets(genso[i],NUM,fp);
		i++;
		if(feof(fp))break;
	}
#if 1
	for(i=0;i<NUM;i++)
	{
		printf("%s",genso[i]);
	}
#endif
	fclose(fp);
	return 0;
}
できました。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: テキストファイルの読み込みが出来なくて困っています。

#12

投稿記事 by softya(ソフト屋) » 13年前

NUMの意味が変わっていますが意識してされたことですか?
ちなみに、このプログラムだと何文字の文字列まで正常に動作するかわかりますか。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

サイクロン

Re: テキストファイルの読み込みが出来なくて困っています。

#13

投稿記事 by サイクロン » 13年前

NUMの意味が変わったのは意識してやっています。
100文字超えたらアウトだと思います。

non
記事: 1097
登録日時: 15年前

Re: テキストファイルの読み込みが出来なくて困っています。

#14

投稿記事 by non » 13年前

15行目 fgets(genso,NUM,fp);
ここ、NUMでいいですか?

20行目 for(i=0;i<NUM;i++)
ここもNUMでいいですか?
non

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: テキストファイルの読み込みが出来なくて困っています。

#15

投稿記事 by softya(ソフト屋) » 13年前

サイクロン さんが書きました:NUMの意味が変わったのは意識してやっています。
100文字超えたらアウトだと思います。
nonさんの指摘のとおりです。
あと100もdefineを希望します。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

サイクロン

Re: テキストファイルの読み込みが出来なくて困っています。

#16

投稿記事 by サイクロン » 13年前

コード:

#include <stdio.h>
#define LINE 40                    //文字列の数
#define NUM 100                  //文字列の文字数

int i,f;

int main()
{
	char genso[LINE][NUM];
	char *tmp;
	FILE *fp;
	fp=fopen("genso.txt","r");	//ファイルの読み込み
	i=0;
	while(1){
		fgets(genso[i],sizeof(genso),fp);
		i++;
		if(feof(fp))break;
	}
#if 1
	for(i=0;i<LINE;i++)
	{
		printf("%s",genso[i]);
	}
#endif
	fclose(fp);
	return 0;
}


non
記事: 1097
登録日時: 15年前

Re: テキストファイルの読み込みが出来なくて困っています。

#18

投稿記事 by non » 13年前

sizeof(genso)
って、具体的にいくつでしょうか?
non

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: テキストファイルの読み込みが出来なくて困っています。

#19

投稿記事 by softya(ソフト屋) » 13年前

for(i=0;i<LINE;i++)
は固定値だとバグになります。
入力していない要素を表示してはいけません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

サイクロン

Re: テキストファイルの読み込みが出来なくて困っています。

#20

投稿記事 by サイクロン » 13年前

コード:

#include <stdio.h>
#define LINE 40
#define NUM 100

int i,flag;

int main()
{
	char genso[LINE][NUM];
	FILE *fp;
	fp=fopen("genso.txt","r");	//ファイルの読み込み
	i=0;
	while(1){
		fgets(genso[i],NUM,fp);
		if(feof(fp))break;
		i++;
	}
	flag=i;
#if 1
	for(i=0;i<flag;i++)
	{
		printf("%s",genso[i]);
	}
#endif
	fclose(fp);
	return 0;
}
できました。
よく考えるとsizeof(genso)は40*100になるんですかね。

non
記事: 1097
登録日時: 15年前

Re: テキストファイルの読み込みが出来なくて困っています。

#21

投稿記事 by non » 13年前

int i,flag;
はローカル変数にしましょう。

で、どの部分を関数にしたいですか?
non

サイクロン

Re: テキストファイルの読み込みが出来なくて困っています。

#22

投稿記事 by サイクロン » 13年前

コード:

FILE *fp;
fp=fopen("genso.txt","r");	//ファイルの読み込み
i=0;
while(1){
	fgets(genso[i],sizeof(genso),fp);
	if(feof(fp))break;
	i++;
}
この、ファイルの読み込み部分です。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: テキストファイルの読み込みが出来なくて困っています。

#23

投稿記事 by softya(ソフト屋) » 13年前

flagは意味不明なので、もっと具体名が良いですね。

で、分離ですがchar genso[LINE][NUM];の引数化と戻り値を考えなくては行けません。
まず、関数プロトタイプだけ書いてみてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

サイクロン

Re: テキストファイルの読み込みが出来なくて困っています。

#24

投稿記事 by サイクロン » 13年前

文字列のポインタを送るだけでいいと思うので、

コード:


#include <stdio.h>
#define LINE 40
#define NUM 100

int readf(char* gensop);    //プロトタイプ宣言
int main()
{
	int i,genso_count;
	char genso[LINE][NUM];
	FILE *fp;
	fp=fopen("genso.txt","r");	//ファイルの読み込み
	i=0;
	while(1){
		fgets(genso[i],NUM,fp);
		if(feof(fp))break;
		i++;
	}
	genso_count=i;
#if 1
	for(i=0;i<genso_count;i++)
	{
		printf("%s",genso[i]);
	}
#endif
	fclose(fp);
	return 0;
}
これで戻り値でgenso_countを返すつもりです。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: テキストファイルの読み込みが出来なくて困っています。

#25

投稿記事 by softya(ソフト屋) » 13年前

問題は、char* gensopですね。文字列のポインタを送るだけだと1つの行しか読めません。
char* gensopとchar genso[LINE][NUM];は対応する型ではありません。
char *gensopと対応する型はchar genso[NUM];です。
それと前のchar **でも違います。この場合はchar*のポインタ型ですのでchar genso[LINE][NUM];では型が一致しません。
と言うことで、char genso[LINE][NUM];の2次元配列を引数にする場合の対応する型を調べてみてください。正解は2種類あります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

box
記事: 2002
登録日時: 15年前

Re: テキストファイルの読み込みが出来なくて困っています。

#26

投稿記事 by box » 13年前

サイクロン さんが書きました:

コード:

	char genso[LINE][NUM];
ここが、仮に

コード:

	char genso[LINE];
とか

コード:

	char genso[NUM];
とかだったら、そのプロトタイプ宣言でいいと思います。
ということは、今のプロトタイプ宣言は正しくない、ということです。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

サイクロン

Re: テキストファイルの読み込みが出来なくて困っています。

#27

投稿記事 by サイクロン » 13年前

コード:

#include <stdio.h>
#define LINE 40
#define NUM 100

int readf(char genso[LINE][NUM])
{
	int i;
	FILE *fp;
	fp=fopen("genso.txt","r");	//ファイルの読み込み
	i=0;
	while(1){
		fgets(genso[i],NUM,fp);
		if(feof(fp))break;
		i++;
	}
	fclose(fp);
	return i;
}
int main()
{
	int i,genso_count;
	char genso[LINE][NUM];

	genso_count=readf(genso);
	for(i=0;i<genso_count;i++)
	{
		printf("%s",genso[i]);
	}
	return 0;
}
無事関数を分けて実行することができました。
ソフト屋さん、nonさん、ありがとうございました。

non
記事: 1097
登録日時: 15年前

Re: テキストファイルの読み込みが出来なくて困っています。

#28

投稿記事 by non » 13年前

>int readf(char genso[LINE][NUM])
前の要素数は省略して
int readf(char genso[][NUM])
と書くのが一般的です。関数にはLINEの要素数は渡されませんので。

softya(ソフト屋) さんが書きました:と言うことで、char genso[LINE][NUM];の2次元配列を引数にする場合の対応する型を調べてみてください。正解は2種類あります。
勉強ですから、もう一つの方法を調べてみることをお勧めします。
non

閉鎖

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