前のページ次のページ上に戻るホーム BREW C++ ライブラリ & GUI フレームワーク & XML ミドルウェア : SophiaFramework UNIVERSE 5.0

15.3. サンプル コード

15.3.1. CSV ファイルの処理

ファイル からカンマで区切られたデータを読み込み、SFXArray に格納します。

例 15.30. データの例 ("/data.csv")

6,8,15,21,4,5

例 15.31. CSV ファイルの格納

SFCError error;                    // エラー値
SFXFile file;                      // SFXFile インスタンス
SFXAnsiStringStreamReader reader;  // ファイル読み込み用ストリーム
SFXAnsiString stringFromFile;      // データが読み込まれる変数
SFXAnsiString csvElement;
SInt32 startOfComma, endOfComma;   // カンマの位置
SInt32 sum;                        // 要素の和
SFXArray<SInt32> array;            // SInt32 型データ要素からなる配列
SFXArray<SInt32>::Enumerator etor; // SInt32 型データ要素からなる配列の列挙子

// 読み込みモードでファイルをオープン
if ((error = file.OpenReadOnly(SFXPath("/data.csv"))) == SFERR_NO_ERROR) {

    // ファイル読み込み用ストリームの取得 ( バッファ サイズ: 1024 )
    if ((error = file.GetStreamReader(1024, &reader)) == SFERR_NO_ERROR) {

        // フェッチする
        if ((error = reader.Fetch()) == SFERR_NO_ERROR) {

            // ファイル読み込み用ストリームバッファから stringFromFile にデータを読み込む
            if ((error = reader.ReadSFXAnsiString(&stringFromFile))
                == SFERR_NO_ERROR) {

                startOfComma = 0;

                // カンマの位置を探す
                endOfComma = stringFromFile.FirstIndexOf(',');

                while (endOfComma >= 0) {   // カンマが見つかる限り繰り返す
                    
                    // 部分文字列を取得する
                    csvElement = stringFromFile.Substring(startOfComma, endOfComma);

                    // 文字列を数字に変換して array に格納する
                    if ((error = array.InsertLast(csvElement.AsSInt32()))
                        != SFERR_NO_ERROR) { // エラーが発生したとき
                        break;
                    }

                    // 次のカンマを探すために startOfComma を設定する
                    startOfComma = endOfComma + 1;
                    // 次のカンマの位置を startOfComma 文字目から探す
                    endOfComma = stringFromFile.FirstIndexOf(',', startOfComma);
                }

                if (error == SFERR_NO_ERROR) {
                    // 最後の文字列を取得する
                    csvElement = stringFromFile.Substring(startOfComma,
                        stringFromFile.GetLength());

                    // 文字列を数字に変換して array に格納する
                    if ((error = array.InsertLast(csvElement.AsSInt32()))
                        == SFERR_NO_ERROR) {

                        // ここで読み込みを完了する

                        // 列挙子を取得する
                        etor = array.GetFirstEnumerator();
                        sum = 0;

                        while (etor.HasNext()) { 
                            // 各要素についての処理
                            SInt32 c;
                            c = etor.GetNext(); // 次の要素を取得する
                            sum += c;           // その要素を加算する
                        }

                        TRACE("%d", sum);
                    }
                }
            }
        }
        reader.Release();
    }
    file.Close();
}

例 15.32. 実行結果

59

15.3.2. リストのソート

リストをソートします。要素の格納には挿入操作が速い SFXList を使います。

例 15.33. リストのソート

SFCError error;                     // エラー値
SFXList<SInt32> list;               // SInt32 型データ要素からなるリスト
SFXList<SInt32>::Enumerator etor;   // SInt32 型データ要素からなるリストの列挙子
SInt32 number[] = {14, 3, 22, -5, 8, 16, 1, 0, -7, -2}; // ソート対象のデータ
SInt32 i, j, ithValue, jthValue;


for (i = 0; i < lengthof(number); ++i) {
    error = list.InsertLast(number[i]);// 配列 number の要素を list に追加する
    if (error != SFERR_NO_ERROR) { 
        // エラーが発生したとき
        // エラー処理
        return;
    }
}

// 挿入ソート
for (i = 1; i < list.GetSize(); ++i) {
    ithValue = list.Get(i);           // i 番目の要素を取得する
    etor = list.GetFirstEnumerator(); // 列挙子を取得する
    for (j = 0; j < i; ++j) {
        jthValue = etor.GetNext();    // 要素を取得した後に列挙子を次に進める
        if (jthValue > ithValue) { 
            list.Remove(i);           // 要素を削除する ( このとき、列挙子は無効になる )
            error = list.Insert(j, ithValue); // 要素を挿入する
            if (error != SFERR_NO_ERROR) {
                // エラーが発生したとき
                // エラー処理
                return;
            }
            break;
        }
    }
}

// 各要素の表示
etor = list.GetFirstEnumerator();
while (etor.HasNext()) {
    TRACE("%d", etor.GetNext());
}

例 15.34. 実行結果

-7
-5
-2
0
1
3
8
14
16
22

15.3.3. SFXList の処理

コレクション クラスには 4 バイトを超える要素を格納できません。要素へのポインターをコレクション クラスに格納して処理します。

例 15.35. SFXList インスタンスの格納

SFCError error;                       // エラー値
SFXList<SFXLinePtr> list;             // SFXLinePtr 型データ要素からなるリスト
SFXList<SFXLinePtr>::Enumerator etor; // リスト要素の列挙子
SFXMTRandom random;                   // 乱数
SFXLinePtr line, ithLine, jthLine;    // SFXLine インスタンスへのポインター
SInt32 i, j;

// 直線を 10 個ランダムに生成してリストに格納する
for (i = 0; i < 10; ++i) {
    // 直線の値をランダムに生成する
    if ((line = new SFXLine(random.GetSInt16(), random.GetSInt16(),
        random.GetSInt16(), random.GetSInt16())) != null) {
        
        // 要素をリストに追加する
        error = list.InsertLast(line);
    }
    else { 
        // 直線の生成に失敗したとき
        error = SFERR_NO_MEMORY;
    }
    if (error != SFERR_NO_ERROR) {
        break;
    }
}

// list に格納された SFXLine インスタンスを始点の X 座標でソートする
if (error == SFERR_NO_ERROR) {
    // 挿入ソート (始点の X 座標を比較)
    for (i = 1; i < list.GetSize(); ++i) {
        ithLine = list.Get(i);            // i 番目の要素を取得する
        etor = list.GetFirstEnumerator(); // 列挙子を取得する
        for (j = 0; j < i; ++j) {
            jthLine = etor.GetNext();     // 要素を取得して次に進める

            // 始点の X 座標を比較
            if (jthLine->GetStartX() > ithLine->GetStartX()) {
                list.Remove(i);           // 要素を削除する ( このとき、インスタンスは削除されない )
                error = list.Insert(j, ithLine); // 要素を挿入する
                break;
            }
        }
        if (error != SFERR_NO_ERROR) {    //エラーが発生したときはループを抜ける
            break;
        }
    }
}

// 最後にインスタンスを必ず削除する
etor = list.GetFirstEnumerator();
while (etor.HasNext()) {
    line = etor.GetNext();
    delete line;
}

15.3.4. 文字列のカウント

SFXHashmap を用いて文字列( 単語 )の出現回数をカウントします。

例 15.36. 文字列のカウント

SFXAnsiString string("abc def def def ghi ghi");         // カウント対象の文字列
SFXHashmap<SFXAnsiString, SInt32> hashmap;               // 単語の出現回数をカウントするためのハッシュ マップ
SFXAnsiString word;                                      // 切り出した単語
Bool isAlphabet = false;                                 // 英数字を処理中のときは true になる
SInt32 startOfWord, endOfWord;
SInt32 i;

// 末尾にダミーの非アルファベット文字を追加する
string += '.';

for (i = 0; i < string.GetLength(); ++i) {
    // string[i] が英数字であるか判定する
    if (SFXAscii::IsAlphaDigit(string[i])) {
        // 英数字を処理中でないとき
        if (!isAlphabet) { 
            startOfWord = i; // 単語の先頭を設定する
            isAlphabet = true;
        }
    } else {
        // 英数字を処理中のとき
        if (isAlphabet) { 
            endOfWord = i;
            // word の切り出し
            word = string.Substring(startOfWord, endOfWord);
            if (hashmap.ContainsKey(word)) { 
                // word が含まれるとき
                // これまでの出現回数を取得する
                SInt32 count = hashmap.Get(word);
                // 回数を 1 加算する
                hashmap.Set(word, count + 1);
            } else {
                // 初めて出現したので、回数を 1 に設定する
                hashmap.Set(word, 1);
            }
            isAlphabet = false;
        }
    }
}

SInt32 n1 = hashmap.Get("def"); // n1 = 3
SInt32 n2 = hashmap.Get("abc"); // n2 = 1
SInt32 n3 = hashmap.Get("jkl"); // n3 = 0