ページ 11

ファイルからデータを読み込み2次元配列に格納

Posted: 2012年4月25日(水) 23:12
by とさんこ
C++の超初心者です。

"fname"というデータファイルにある6つの数値データを読み込んで2次元の配列に格納するプログラム"test"を作成したいです。

"fname" の中身は、以下のようになっています。各数値の後にコンマ","をつけてありますが、ついていないデータの読み込みでも結構です。ただ、できればデータは2列のものを読み込みたいと思っています。

1, 7,
2, 8,
3, 9,

格納させるプログラム"test"を以下のように作成してみました。

#include <iomanip>
#include <fstream>
#include <cstdio>
#define NO1 3
#define NO2 2
using namespace std;

int main()
{

FILE *ifs;
int a,b,i,j,map[NO1][NO2];
char fname[32],ch;

ifs=fopen(fname,"r");

if (!ifs) {
cerr << "File not open" << endl;
return -1;
}

for(i=0; i<NO1; i++)
{
for(j=0; j<NO2; j++)
{

do{ch=(getc(ifs));}

while(ch==','||ch=='\n'||ch=='\r');

map[j] = ch - '0';

cout << "map[" << i << "][" << j << "]= " << map[j]
<< endl;

}
}
cout << "\n" << endl;

return 0;

}
-------------------------------------------------------------

上記のプログラムで、

map[0][0]=1
map[0][1]=7
map[1][0]=2
map[1][1]=8
map[2][0]=3
map[2][1]=9

という風に格納にしたいです。

しかし、このプログラムをコンパイルすると、"File not open"と出てきます。つまり、ファイルがうまく格納されていません。

どなたかわかる方がいらっしゃれば、具体的にどのような形にすればよいか、ご指導願います。

Re: ファイルからデータを読み込み2次元配列に格納

Posted: 2012年4月25日(水) 23:47
by box
とさんこ さんが書きました:

コード:

  char fname[32],ch;
       ifs=fopen(fname,"r");
しかし、このプログラムをコンパイルすると、"File not open"と出てきます。つまり、ファイルがうまく格納されていません。
fname[]という変数に何も値が入っていない状態ですから、
「ファイルが見つからない」というエラーが出るのは当然でありましょう。
ファイル名が"fname"固定であれば、

コード:

       ifs=fopen("fname","r");
でいいような気がします。

文字列リテラルとchar型の変数との区別が付いていないように思います。

Re: ファイルからデータを読み込み2次元配列に格納

Posted: 2012年4月26日(木) 11:42
by とさんこ
ご回答ありがとうございます。

以下のように教えて頂いただいたように、fname→"fname"という風にファイル名をクオーテーションマークで囲ってみました。
box さんが書きました:コード[C++]: 全て選択1 ifs=fopen("fname","r");でいいような気がします。
これでコンパイルはできたのですが、以下のような出力結果となりました。

$ ./a.exe
map[0][0]= -16
map[0][1]= -16
map[1][0]= -16
map[1][1]= -16
map[2][0]= 1
map[2][1]= -16

おっしゃる通り、まだ文字列やchar型の変数について勉強不足なところが多々あります。このあたりをもう少し勉強する必要があると思います。今後埋めていきたいと思います。

何か、もう少しプログラム作成上の具体的なヒント等がございましたら、お手数ですがご教授願います。

Re: ファイルからデータを読み込み2次元配列に格納

Posted: 2012年4月26日(木) 12:12
by beatle
fnameファイルの中に無駄な空白文字が含まれているんじゃないでしょうか。

Re: ファイルからデータを読み込み2次元配列に格納

Posted: 2012年4月26日(木) 12:28
by softya(ソフト屋)
まず、ソースコードはcodeタグをお使い下さい。 詳しくはフォーラムルールを。 http://dixq.net/board/board.html

コード:

#include <iomanip>
#include <fstream>
#include <cstdio>
#define NO1 3
#define NO2 2
using namespace std;

int main()
{

  FILE *ifs;
  int a,b,i,j,map[NO1][NO2];
  char fname[32],ch;

       ifs=fopen(fname,"r");

       if (!ifs) {
         cerr << "File not open" << endl;
         return -1;
       }

  for(i=0; i<NO1; i++)
  {
  for(j=0; j<NO2; j++)
  {

        do{ch=(getc(ifs));}

        while(ch==','||ch=='\n'||ch=='\r');

          map[i][j] = ch - '0';

  cout << "map[" << i << "][" << j << "]= " << map[i][j]
       << endl;

       }
}
      cout << "\n" << endl;

    return 0;

  }
インデントが出鱈目なのですごく読みづらいコードですので、まずインデントを整形します。

コード:

#include <iomanip>
#include <fstream>
#include <cstdio>
#define NO1 3
#define NO2 2
using namespace std;

int main()
{

	FILE *ifs;
	int a, b, i, j, map[NO1][NO2];
	char fname[32], ch;

	ifs = fopen( fname, "r" );

	if ( !ifs ) {
		cerr << "File not open" << endl;
		return -1;
	}

	for( i = 0; i < NO1; i++ ) {
		for( j = 0; j < NO2; j++ ) {

			do {
				ch = ( getc( ifs ) );
			} while( ch == ',' || ch == '\n' || ch == '\r' );

			map[i][j] = ch - '0';

			cout << "map[" << i << "][" << j << "]= " << map[i][j]
			     << endl;

		}
	}
	cout << "\n" << endl;

	return 0;

一旦投稿します。

Re: ファイルからデータを読み込み2次元配列に格納

Posted: 2012年4月26日(木) 12:34
by softya(ソフト屋)
で処理ですが、あえてC言語のfopenを使う必要は無いと思います。
ifstreamを使えばそんなに苦労しなくて良いんじゃないんでしょうか?
使い方はcinとほぼ同じです。
「C++編(標準ライブラリ) 第33章 ファイルストリーム」
http://www.geocities.jp/ky_webid/cpp/library/033.html

Re: ファイルからデータを読み込み2次元配列に格納

Posted: 2012年4月26日(木) 18:08
by とさんこ
> beatle さん

そうですね、読み込むテキストファイルから空白を消したらうまく配列にデータを渡せるようになりました。
ありがとうございます。

> softya さん

すみません、フォーラムルールをよく読んでいませんでした。以後気をつけます。
ifstreamを使うともう少し簡潔に書くことができるのでしょうか。とりあえず、示して頂いたリンク等を参考に、ifstreamでの書き方も後ほど勉強しようと思います。ありがとうございます。