>>  Main > Programing > DMemo > 0001

D言語に関する覚え書き - Dメモ

0001 - テキストファイルから1行だけ読みこむ

コード

////////////////////////////////////////////////////////////////////////////////////////////////////
///    テキストファイルから1行だけ読みこむ
///    
///    テキストファイルがUTF-8, UTF-16, UTF-32である仮定で、
///    \rまたは\nが出てくるまでを1行として、読み込む。
///    ここではchar[]型で読み込んでいる。
///    
///    Date:        June 28, 2007
///    Authors:    SHOO
///    License:    NYSL
import tango.io.Stdout;
import tango.io.FileConduit;
import tango.text.convert.UnicodeBom;
import tango.core.Array;
int main(){
    auto file = new FileConduit("test.txt");
    auto bom = new UnicodeBom!(char)(Encoding.Unknown);
    char[256] buf;
    char[] result;
    char[] temp;
    size_t pos;
    while(file.length != file.position){
        temp = bom.decode( buf[0..file.read(buf)] );
        pos = temp.findIf((char a){return a=='\r' || a=='\n';});
        if(pos == temp.length){
            result ~= temp;
        }else{
            result ~= temp[0..pos];
            break;
        }
    }
    Stdout(result).newline;
    
    return 0;
}

コメント

う~ん、なんかスマートじゃないなぁ…。
特に file.length != file.position のあたり
file.eofみたいな、ファイル終端を調べる関数でもあればいいんだけど…
UnicodeFile使おうかとも思ったのですが、一気に読みこむってのがちょっと非効率的かなって。
テストの際にはtext.txtファイルを適当に書いて読み込ませてます。

参考文献

0002 - TangoでDLLを作成する

準備

DMD 1.021をダウンロードしてきて解凍。
保存先は C:\dmd および C:\dm が作られる設定。
DSSS 0.71 をダウンロードしてきて解凍。
保存先は C:\dmd\bin\dsss.exe が作られる設定。
コマンドプロンプトを立ち上げ、 C:\dmd\ をカレントディレクトリにする
dsss net install tango
としてTangoをインストール。途中Phobosに戻せないがよいかと聞かれるがYとして続行。
これでTangoとDSSSが使用できる環境が完成する。
別の方法をとってもTangoとDSSSが利用できればよい。
上記設定で
C:\dmd\etc\rebuild\dmd-win-tango
をメモ帳で開き、その72行目を
dylibs=no
から
cmd=dmd $i $o.def -of$o.dll
と変更する。
適当なフォルダ(ここでは C:\project とする)を作り、その中に
main.d, main.def, test.d というファイルをそれぞれ作成する。
main.dとtest.dはUTF-8で作成した。

main.d

module main;

import tango.sys.win32.Types;
import tango.sys.win32.UserGdi;

HINSTANCE g_hInst;

extern (C){
    void gc_init();
    void gc_term();
    void _minit();
    void _moduleCtor();
    void runModuleUnitTests();
}

extern(Windows) BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved){
    switch (ulReason){
    case DLL_PROCESS_ATTACH:
        gc_init();            // GC初期化
        _minit();            // モジュールリスト初期化
        _moduleCtor();        // モジュールコンストラクタ実行
        runModuleUnitTests();        // 単体テスト実行
        break;
    case DLL_PROCESS_DETACH:
        gc_term();            // GC終了
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        return false;
    }
    g_hInst=hInstance;
    return true;
}


export extern(Windows)
void func(){
    MessageBoxA(null, "dlltest\0".ptr, "dlltest\0".ptr, 0);
}

test.d

module test;

import tango.sys.win32.UserGdi;

int main(){
    auto hMod = LoadLibraryA("dll.dll\0".ptr);
    alias extern(Windows)void function() FUNC;
    auto func = cast(FUNC) GetProcAddress(hMod, "func\0".ptr);
    func();
    FreeLibrary(hMod);
    return 0;
}

main.def

LIBRARY         DLLTEST
DESCRIPTION     'Dll Test'

EXETYPE        NT
CODE            PRELOAD DISCARDABLE
DATA            PRELOAD SINGLE

EXPORTS
        func       @2

コンパイル前準備

C:\dmd>cd C:\project
C:\project>PATH=C:\dmd\bin

コンパイル

C:\project>dsss build -dylib main.d
main.d => main
+ C:\dmd\bin\rebuild.exe -Idsss_imports\ -I. -S.\ -IC:\dmd\i
nclude\d -SP:\bin\D\dmd_tango\lib\ -dylib  -IC:\dmd\include\
d -SC:\dmd\lib  -oqdsss_objs  main.d -ofmain
C:\dmd\bin\..\..\dm\bin\link.exe dsss_objs\_main,main.dll,,u
ser32+kernel32,main.def/noi+.\\+C:\dmd\lib\\+C:\dmd\lib\;
OPTLINK (R) for Win32  Release 7.50B1
Copyright (C) Digital Mars 1989 - 2001  All Rights Reserved

.\\main.res
 Warning 2: File Not Found .\\main.res
C:\dmd\lib\\main.res
 Warning 2: File Not Found C:\dmd\lib\\main.res
C:\dmd\lib\main.res
 Warning 2: File Not Found C:\dmd\lib\main.res


C:\project>dsss build test.d
test.d => test
+ C:\dmd\bin\rebuild.exe -Idsss_imports\ -I. -S.\ -IC:\dmd\i
nclude\d -SP:\bin\D\dmd_tango\lib\  -IC:\dmd\include\d -SC:\
dmd\lib  -oqdsss_objs  test.d -oftest
C:\dmd\bin\..\..\dm\bin\link.exe dsss_objs\_test,test,,user3
2+kernel32/noi+.\\+C:\dmd_tango\lib\\+C:\dmd\lib\;

実行

C:\project>test

コメント

という感じで、なんかよくわからない警告は出るものの、一応のことコンパイルおよび実行ができるようでした。
あ、ちなみに、実際やってみた際にはこのページを参考に InterleavingIterator を使ってみたりしました。
DFLも一緒に使ってみたりしたけれど、DFL(0.96)のSocketが最新のTango(0.99.1 RC4)に対応していないらしく、importするモジュールをいろいろ考えなければならなかった…
一応のこと成功したけれど。
リンカの警告の原因と消し方を知っている方がいらっしゃいましたら下記フォームから情報をお寄せください。

0003 - 条件にマッチしたファイル名を変更する

コード

module main;
// 必要な定義をインポート
// 出力
import tango.io.Stdout:Stdout;
// ファイル操作
import tango.io.FilePath:FilePath;
// 正規表現
import tango.text.Regex:Regex;
// 文字列を整数へ、整数を文字列へ変換する
import tango.text.convert.Integer:toInt, format, Style, Flags;

int main(){
    // 現在のフォルダを検索する
    auto fp = new FilePath(".");
    // 正規表現で、 {番号}-{ファイル名}.txt にマッチするものと表現
    auto regex = Regex(r"(\d+)(-.+.txt)", "");
    // リストで、フォルダをはじいてすべてに対して
    foreach(f;fp.toList){
        // ファイルが、
        // - フォルダではなく(つまりファイルで、)
        // - 正規表現にマッチして
        // - 番号が7番以上
        // のもののみを選定
        if(   !f.isFolder
        &&    regex.test( f.file() )
        &&    toInt(regex.replace("$1"))>=7
        ){
            // 番号を取得
            auto fnum = toInt(regex.replace("$1"));
            // 1増やした0埋め2桁の番号を生成
            auto fnumstr = format(new char[2], fnum+1, Style.Unsigned, Flags.Zero);
            // 出力用に一度保存
            auto oldname = f.file();
            // 新しいファイル名を作成
            auto newname = regex.replace(fnumstr ~ "$2");
            // ファイル名を変更
            f.rename(newname);
            // 出力
            Stdout("ファイル名を、[")(oldname)("]から[");
            Stdout(newname)("]に変更しました。").newline;
        }
    }
    return 0;
}

コメント

連番をつけた。 6番目のファイルの内容を分割することになり、7番以降の番号を1づつ増やして修正する必要が出た。 ファイルの量がかなり多い。 めんどい。 これからもこういう変更とか多そうだ…
という需要に駆られてちょこちょこっと組んでみました。
最初はFlexibleRenamerとか使おうかとも思ったのですが、ちょっと頑張っても連番の一部の名前だけ変更するとか難しそうだったので、もういっそ…と思ってD言語でやっちゃいました。
ふつうPerlとかでやるような気もしますが、もうPerlなんて忘れてしまったので…。 D言語でもTangoを使えば意外にも簡単に書けます。 API探すのが大変ですが…(汗
あとDの正規表現は遅いとか言われることも多いようですが、ぶっちゃけこの程度の処理ならこの速度で十分です。 逆にそれ以上の速度を求める場合は正規表現なんて使っちゃダメかと。

0004 - TangoのCollectionについて。ちょっと翻訳してみた。

翻訳

長いのでテキストファイルにしました。右クリック>対象をファイルに保存とかしてテキストエディタなどで見てください。
download

コメント

ちょっと古いので今のものとは若干違うかもしれません。
自分が理解するために訳した際のファイルをそのまま上げているので、かなりみにくいと思います。本家と見比べていくといいかと思います。
かなり意訳で、違約が含まれるかもしれません。その時はこちらからツッコミでもしていただけたらと思います。
あなたのツッコミ、お待ちしt(ry
英語なんてなくなればいいのに…
Copyright©SHOO All rights reserved. / LastModified : 2007/12/12(水)[20:38:36]