C言語すげえ

注意:Cというプログラミング言語ではなく標準ライブラリについてです。

#include <stdlib.h>
long int strtol(const char *nptr, char **endptr, int base);


longで表しきれなくなったとき、正か負かによってLONG_MAXやLONG_MINが返ります。intを得たい場合や、longのうち最大値と最小値の2つを諦めるならばこれで十分(嫌ならグローバル変数errorno参照)。
endptrには変換終了時の文字へのポインタが入る。nptrが""でなく(*nptrが'\0'でなく)、*endptrが'\0'ならば文字列全体が正常に数値に変換できたことになる。情報がいらないならNULLを渡してもよい。でもそれならatoiで(ry
baseにはその名の通り基数を指定します。A-Zまでの文字が使えるので36進数までいけそうですね(baseにそれ以上の数を入れると落ちるか通るけど表せない数が出るのかはしらん)。


strtolとかただのatoiのlong版だと思っていたのがそもそもの原因でした。不覚。
ついでにatoiのfloat版がatof、strtolのdouble版がstrtod。
同じくstrtodは高機能です。
特に言語処理系でこのあたりのオーバーフロー等の処理も含めて厳密な変換を行いたいなら便利でしょう。無駄にエラー列数まで得られます(多分本来の用途(トークナイズ)と違うけど)。C++派にも使える場面はあると思います。
まあ簡単変換(効率はともかくメモリ管理の心配なし)ではboost::lexical_castでしょう。「おかしかったら例外を投げる」はエラー処理の点でもうれしいもの。文字列を外部ファイルから読むとかよくありすぎるし例外ないと死ねる。エラー処理とかスルーする場合でもOK。・・・TR1に入らないの???
・・・やはりTR1が入ったとしてもboostなしではC++でまともにプログラムを書くことすらままならぬか・・・。
どっかにはlexical_castはC++0xの採用候補(candidate)だとか書いてあったけどどっかいっちゃったのかなあ・・・。なんだかんだでboostは重いんだよ(ファイル数的な意味で)。
以上、C++でまともなソフトを書いていないことの暴露でした。とらえようによってはこれから書こうという風にもとれる。スーパーうにょうにょ(3D)ってC++でできてるんだぜ・・・。


ここからググり

  • ちなみにExceptional C++ Styleという本にでは17ページほど数値・文字列変換について書かれているらしいぞ!
  • 東大のプログラミング応用ではC++ boostをやるのか・・・。hared_ptr/format/lexical_cast/tokenizer/regex。恐ろしいものよ。