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 )を用いる。