ページ 11

C++のファイル入力

Posted: 2013年5月13日(月) 08:07
by ダン
C++のファイル入力の話です。
<すでにやっている事>
 fstreamを使ってtextファイル内の文字列(数字です)をstring型のバッファに格納し、
 その後、バッファの中を読んで数字変換(-48させる)した後、
 用意した二次元配列に格納していく、といったことです。

<今回やりたい事>
 それを「ファイルを読む〜数字変換していく」Aクラスと「Aクラスで変換されたデータが格納された二次元配列がある」Bクラス、とに分けたいのです。

 で、Aクラスにおいては数値を格納する二次元配列を作らず、
 バッファから一文字ずつ変換しながらBクラスの二次元配列にゴンゴン格納したいのですが
 やり方としては、Bクラスのメンバに引数で受け取った値を二次元配列に入れてく関数を作り、
 それをAクラスの変換後に設置する、という考えしか思い浮かびません。
 しかし、その場合
 Aクラスの方でどうその関数を定義し、どうループさせたらいいのか(二次元配列内を移動させながら格納させるわけですよね?)わかりません。

 Bクラスに、引数で受け取った値を二次元配列に格納する関数を置くとして、
 void 格納(int value){ }この関数内で二次元配列に格納していく二重ループを作るべきなんでしょうか?
 なんかイメージが出来ません、ご教授お願い致します。

Re: C++のファイル入力

Posted: 2013年5月13日(月) 10:02
by usao
二次元配列のサイズ(読み込むべき要素数)は,前もってわかるのでしょうか?
(例えば,
 ・サイズは固定な仕様である
 ・ファイル先頭に書かれている
 等…)

そうだとして(少なくとも行方向の要素数は前もってわかっていると予想しますが)

・Bのためにファイルからデータを読んで,Bに引き渡すクラス A
・データ実態(2次元配列)を保持する役割を持つクラス B
の2つを作りたい, ということだとすると…
自分だったら なんとなくな流れは 以下のような感じに書くかもしれません.
この場合だと,2重ループは A::LoadFromFile()の中になりますね.

コード:

class B  //格納側はこんな
{
public:
    B( size_t nRow, size_t nCol ){  nRow*nColの要素を格納できる準備をする  }
    void SetData( size_t row, size_t col, int val ){   配列の[row][col]にvalを格納  }
    size_t Get_nRow() const {  配列の行数を返す  }
    size_t Get_nCol() const {  配列の列数を返す  }
};

class A  //読込処理側はこんな
{
public:
    A( B &rB ) : m_rB(rB) {} 
    bool LoadFromFile( const char *filename )
    {
        //ここで2重ループ.読んだ値をm_rB.SetData()で格納しまくる
        //m_rB.Get_nRow(),   m_rB.Get_nCol()  で配列のサイズがわかる
    }
private:
    B &m_rB;
};

int main()
{
    //ここでは仮に,2次元配列のサイズはわかっているものとする
    B b( 5,8 );  //bは,前もって [5][8] サイズの配列を準備する
    A a( b );  //aは,ファイルから読み取ったデータを格納する相手への参照をメンバに持つ
    a.LoadFromFile( filename );  //ファイルロード
}

Re: C++のファイル入力

Posted: 2013年5月13日(月) 17:10
by ISLe
Bはクラスとして定義する必要があるのでしょうか。
例えばstd::vectorを使ってこういうことができますけど。

コード:

#include <iostream>
#include <vector>

template<class T>
class myvector : public std::vector<T> {
public:
	T& operator[](int i) {
		if (this->size() <= i) {
			this->resize(i+1);
		}
		return std::vector<T>::operator[](i);
	}
};
typedef myvector<myvector<int> > B;

int main()
{
	B b;
	b[0][0] = 100;
	b[3][1] = 131;
	for (int i=0; i<b.size(); i++) {
		for (int j=0; j<b[i].size(); j++) {
			std::cout << b[i][j] << " ";
		}
		std::cout << std::endl;
	}
	return 0;
}

Re: C++のファイル入力

Posted: 2013年5月14日(火) 08:48
by ダン
usaoさん、ISLeさん、回答ありがとうございます。
おかげで自分のやりたいことが実装出来ました。
お二人の助言のおかげです!ありがとうございました!