d. 2次元(x, y)データのセーブ・ロード用パーツの作成
1.プロジェクト名DataCollのビジュアル・ビルダーを起動する。
2.「パーツ」->「新規作成」をクリックする。
DataColl.vbbに、これから作成するパーツFileXYを格納する。
3.FileXYパーツを作成する。
非ビジュアル・パーツ |
|
FileXYパーツの機能設定 |
|
クラス名 |
FileXY |
説明 |
データ(x, y)のロード・セーブ |
ファイル名 |
DataColl |
パーツ・タイプ |
非ビジュアル・パーツ |
基底クラス |
IStandardNotifier |
.hpvファイル |
"FileXY.hpv" |
.cpvファイル |
"FileXY.cpv" |
インクルード・ファイル |
"DataXY.hpp" _DATAXY_ <ivseq.h> _IVSEQ_ <fstream.h> _FSTREAM_ |
FileXYパーツ | |||
属性 |
タイプ |
コメント |
優先 |
itemsFilename |
IString |
ファイル名の設定 |
|
type |
IString |
データ間の区切り方 commentまたはspace |
|
items |
IVSequence<DataXY*>* |
全データ |
O |
set関数の引数のconstを削除 |
|||
アクション |
タイプ |
パラメータ |
|
exportToFile |
long |
const IString& filename |
O |
importFromFile |
long |
const IString& filename |
O |
save |
long |
|
|
saveAs |
long |
const IString& filename |
|
open |
long |
const IString& filename |
|
newFile |
void |
|
O |
4.「ファイル」->「保管および生成」->「フィーチャー・ソース」をクリックし、
FileXY.cpvとFileXY.hpvを自動作成する。
5.exportToFile()、importFromFile()、save()、saveAs()、open()とnewFile()を
下記のようにコーディングする。
long FileXY::exportToFile(const IString& filename)
{
ofstream ofStream;
DataXY* iExportItem;
long iCount=0;
IVSequence<DataXY*>::Cursor SeqCursor( *iItems );
ofStream.open( filename ); // ファイルのオープン
if( !ofStream ) // 例外処理
{
IString errorText = IString( "ファイル" ) + filename + "をオープンできません。";
IException exc( errorText, 0, IException::unrecoverable );
ITHROW( exc );
} // 例外処理終了
if( iType=="comma" ) // データ間をコンマで区切る場合
{
for( SeqCursor.setToFirst(); SeqCursor.isValid(); SeqCursor.setToNext() )
{
iExportItem = iItems->elementAt( SeqCursor );
ofStream << iExportItem->dataX() << "," << iExportItem->dataY() << endl;
iCount++;
}
}
if( iType=="space" ) // データ間をスペースで区切る場合
{
for( SeqCursor.setToFirst(); SeqCursor.isValid(); SeqCursor.setToNext() )
{
iExportItem = iItems->elementAt( SeqCursor );
ofStream << iExportItem->dataX() << " " << iExportItem->dataY() << endl;
iCount++;
}
}
ofStream.close(); // ファイルのクローズ
return iCount;
}
long FileXY::importFromFile(const IString& filename)
{
ifstream ifStream;
DataXY* iImportItem;
long iCount=0;
double iDataX;
double iDataY;
char iCharacter;
IString iText;
ifStream.open( filename ); // ファイルのオープン
if( !ifStream ) // 例外処理
{
IString errorText = IString( "ファイル" ) + filename + "をオープンできません。";
IException exc( errorText, 0, IException::unrecoverable );
ITHROW( exc );
} // 例外処理終了
// itemsのイベント通知機能を禁止
iItems->disableNotification();
if( iType=="comma" ) // データ間をコンマで区切る場合
{
// 最後のデータまで繰り返す。
while( !ifStream.eof() )
{
// DataXY型のiImportItemの実体(オブジェクト)を生成
iImportItem = new DataXY;
// ファイルからデータをdataX、コンマ、dataYの順に取り出す。
ifStream >> iDataX >> iCharacter >> iDataY;
// iImportItemにdataXとdataYを代入する。
iImportItem->setDataX( iDataX );
iImportItem->setDataY( iDataY );
// iItemsの最後に加える。
iItems->addAsLast( iImportItem );
iCount++;
}
}
if( iType=="space" ) // データ間をスペースで区切る場合
{
// 最後のデータまで繰り返す。
while( !ifStream.eof() )
{
// DataXY型のiImportItemの実体(オブジェクト)を生成
iImportItem = new DataXY;
// ファイルからデータをdataX、dataYの順に取り出す。
ifStream >> iDataX >> iDataY;
// iImportItemにdataXとdataYを代入する。
iImportItem->setDataX( iDataX );
iImportItem->setDataY( iDataY );
// iItemsの最後に加える。
iItems->addAsLast( iImportItem );
iCount++;
}
}
// itemsの最後のオブジェクトのポインターを取得する。
// このままでは、最後のデータが2回入るため。
iImportItem = iItems->lastElement();
// オブジェクトのポインターを削除する。
iItems->removeLast();
// オブジェクトを削除する。
delete iImportItem;
iCount -=1;
ifStream.close(); // ファイルのクローズ
// itemsのイベント通知機能を開始
iItems->enableNotification();
// itemsのイベントを通知する。
notifyObservers(INotificationEvent(FileXY::itemsId, *this));
return iCount;
}
long FileXY::save()
{
return exportToFile( iItemsFilename ); // exportToFileを実行する。
}
long FileXY::saveAs(const IString& filename)
{
long iCount;
iCount = exportToFile( filename ); // ファイルへ保存
setItemsFilename( filename ); // 変更したファイル名を記憶する。
return iCount;
}
long FileXY::open(const IString& filename)
{
long iCount;
newFile(); // 既存のデータ(proxyItems)をすべて削除する。
iCount = importFromFile( filename ); // ファイルから読み込む。
setItemsFilename( filename ); // 開いたファイル名を記憶する。
return iCount;
}
void FileXY::newFile()
{
// itemsの全ての項目がなくなるまで繰り返す。
while( !iItems->isEmpty() )
{
// itemsの最初のオブジェクトのポインターを取得する。
DataXY* iImportItem = iItems->firstElement();
// オブジェクトのポインターを削除する。
iItems->removeFirst();
// オブジェクトを削除する。
delete iImportItem;
}
return;
}
6.後でパーツFileXYを使えるように、覚え書きFileXY.htmlを書く。
パーツFileXYの説明
2次元(x, y)データをセーブおよびロードするためのパーツである。
FileXYパーツ | |||
属性 |
タイプ |
コメント |
優先 |
itemsFilename |
IString |
ファイル名の設定 |
|
type |
IString |
データ間の区切り方 commentまたはspace |
|
items |
IVSequence<DataXY*>* |
全データ |
O |
アクション |
タイプ |
パラメータ |
|
exportToFile |
long |
const IString& filename |
|
importFromFile |
long |
const IString& filename |
|
save |
long |
|
|
saveAs |
long |
const IString& filename |
|
open |
long |
const IString& filename |
|
newFile |
void |
|
O |
データのセーブの仕方
1.データ間をコンマで区切る場合は、属性typeを文字列commaにする。例:1.3,6.54
2.データ間をスペースで区切る場合は、属性typeを文字列spaceにする。例:1.3 6.54
ファイルを開くにはopen( filename )、データの上書保存にはsave ()、データの別名保存は
saveAs( filename )を用いる。