Big Sky :: clib の使い勝手にマジ感動した
C言語でアプリケーションを書くのは他の言語と比べて少し気合が必要ですよね。例えば HTTPからデータを取得する 取得したデータを json パースする 結果の一部を色付きで表示する こんな場合、C言語...
http://mattn.kaoriya.net/software/lang/c/20140627222830.htm
locale-string.c
最近のライブラリは文字列が utf-8 前提で書かれている物が多く、Windows だと「それ、ツライわー(汗)」だったりするのですが、かと言ってこれだけの為に変換ライブラリを入れるのはアレですし、iconv 入れちゃったら GPL(LGPL) だし仕事で使えねー、みたいな事が起きてしまいます。でもロケール文字列と utf-8 との変換なら mbstowcs や wcstombs があれば出来るし、Windows なら MultiByteToWideChar や WideCharToMultiByte があれば出来るので、それだけのライブラリを書きました。
mattn/locale-string.c - GitHub使い方は簡単。
https://github.com/mattn/locale-string.c
setlocale(LC_CTYPE, "");
const char* ptr = "こんにちわ世界";
char* mbs = utf8_to_locale_alloc(ptr);
assert(NULL != mbs);
char* utf8 = utf8_from_locale_alloc(mbs);
assert(NULL != utf8);
assert(0 == strcmp(ptr, utf8));
使い終わったら free が必要。utf8_to_locale_alloc で utf-8 文字列をロケール文字列へ、utf8_from_locale_alloc でロケール文字列から utf-8 へ変換します。Linux や Mac だと必要ない機能なのでマクロを用意してあります。
#ifdef _WIN32
# define UTF8_ALLOC(p) utf8_from_locale_alloc(p)
# define UTF8_FREE(p) free(p)
# define LOCALE_ALLOC(p) utf8_to_locale_alloc(p)
# define LOCALE_FREE(p) free(p)
#else
# define UTF8_ALLOC(p) (p)
# define UTF8_FREE(p)
# define LOCALE_ALLOC(p) (p)
# define LOCALE_FREE(p)
#endif
Windows 以外ならばメモリ確保も解放も行いませんので、UTF8_ALLOC して使い終わったら UTF8_FREE しておくと UNIX でも Windows でも同じ様に動作する、という仕組みです。wcwidth.c
皆さんしってる wcwidth です。wcwidth, wcswidth, wcwidth_cjk, wcswidth_cjk がそろっていますが、オマケで utf-8 文字列の幅を求める string_width と string_width_cjk も付いてきます。
mattn/wcwidth.c - GitHub
https://github.com/mattn/wcwidth.c
assert(14 == string_width("こんにちわ世界"));
assert(20 == string_width("こ★ん■に●ち▲わ☆世◆界"));
assert(26 == string_width_cjk("こ★ん■に●ち▲わ☆世◆界"));
こんな感じに使います。ansicolor-w32
最近の Linux のアプリケーションでコンソールに色付きで出力される物も最近では珍しくなくなってきました。ただ Windows だと API が超メンドクサイので Constellation さんの console-colors.c を使うのが良いのですが、UNIX 系ツールを移植していてなるべくオリジナルコードを触りたくない場合にはツライんです。
mattn/ansicolor-w32.c - GitHubそこで ansicolor-w32.c というのを書きました。
https://github.com/mattn/ansicolor-w32.c
ansicolor-w32.h
を include すると、エスケープシーケンスを解析して Windows でも色付けで表示してくれます。ansicon というツールも存在しますが、このライブラリはそれ無しでも色付け可能です。
fprintf, fputs, printf, puts だけ対応しています。
#include <stdio.h>
#ifdef _WIN32
# include "ansicolor-w32.h"
#endif
int
main(int argc, char* argv[]) {
printf("\x1b[2J\x1b[10,10H\x1b[24m\x1b[30m");
printf("\x1b[42m博\x1b[43m多\x1b[46mの\x1b[45m塩\x1b[0m");
return 0;
}
例えばこんなコードを書いて実行すると
この様に表示されます。
よろしければお使い下さい。MIT ライセンスです。