読者です 読者をやめる 読者になる 読者になる

Gobble up pudding

プログラミングの記事がメインのブログです。

MENU

どんな列(幅)でも行数でも読込む関数作りました

スポンサードリンク

f:id:fa11enprince:20150730082027j:plain
C言語を使っているとC++などのようなstringが使えないせいで
可変長の文字列を含んだファイルを読込むときは
非常に泥臭いことをしないといけない。。。か、もしくは
決めうちで列幅を固定してしまったりすることが多いと思います。

そんなわけでどんなに列幅があってもどんなに行数があっても
簡単に読込める関数を作りました。勉強を兼ねて。
作るところで、簡単にできるだろうと目論んでいましたが、
やってみると盛大にバグりました。
細かいミスがすごい出ました。しかも不具合の原因がすぐにわからない。
久々にC言語のキツさを思い知りました。
低レイヤーの言語って泥臭いけど楽しいですよね。

そんなわけでGistに書いたコードをペタリ。
うまくいかず少し発狂しました(´・ω・`)
なんかまだ怪しいところがあるのでここはマズイというのを見つけた方は教えてください。
面倒なんで1ファイルで書きました。
gdbがいまだにうまく使いこなせません……。

使い方

こんな感じです。
2次元配列的な構造を列幅、行数を意識せずに取得できるようにしたものです。
もちろん、ヘッダに分離させてソースコードを置いたらincludeとかしないとダメですが。

int main(void) {
    WholeData *wholeData = getWholeData("test.txt");
    for (int i = 0; i < wholeData->length; i++) {
        printf("%s\n", wholeData[i].lineData->line);
    }
    deallocateWholeData(wholeData);
    return 0;
}

ソースコード

実行した結果はオプションなしのcatと一緒。argvで受け取ってはいませんが。
使用したコンパイラはgcc 4.9.3 (C99)
includeするものが微妙に違う気がしますが
おそらくVisual StudioのC言語でもほぼ同じコードで動くと思われます。
defineを使っているところでメモリの確保サイズの初期値を変えることができます。

どんな幅でも読込む関数作った

書き終わってから気づきました(´;Д;`)。
WholeDataの引数渡してる意味が全くないん。。。設計ミス(^o^)/

明らかに作りがおかしいので直しました。
それにしてもこんな簡単なコードすら書くのが難しいCはツラい。
だからといってもっと上位レイヤーの言語、Ruby, Pythonで何かアプリを作るのは簡単か?
っていうとそんなこともないんですけどね。
難しい部分の種類が違いますよね。
うーんバグがある気がプンプン……まぁ……
f:id:fa11enprince:20160126030153j:plain
いや、ツッコミください(*´Д`)

追記

この記事を書いた後、別のコード例を紹介してくださった記事がありました。
saito.hatenablog.jp
ソースコードを見ると綺麗で無駄がなく、ヘンテコな構造体を定義していなく
普通の用途で使うならこれがいいのでは?
という素晴らしいコードでした。解説もわかりやすいです!
C言語では文字列の長さそんなに気にする機会ないんだよなぁと思い出しました。
どうせNULL('\0')で終端するので。