16進数TCHAR文字列をunsigned int にする方法

[戻る]
なおぞう 2016/02/17(水) 17:54:56
お世話になります。

VS2013 Unicode文字セット 標準Windowsライブラリを使用する
の環境で開発しています。

ファイル名 test_FFFFFFFF.txt が存在するとして、ファイル名のIndexとなっている
FFFFFFFFを、unsigned int に置き換えたいのですが、良い方法がないかと探していると
ころです。

16進数をintに変えるというので探したところ、
int i;
StrToIntEx(TEXT("0xFFFFFFFF"), STIF_SUPPORT_HEX, &i);
で数値を取得し、-1のままでは困るので、
unsigned int ui = i;
とする方法が見つかりました。

この関数の第一引数(変換元文字列)には、ちゃんと16進だという 0x を付けないと駄目
なようです。
スマートに16進文字列をunsigned intに変更する方法がないかと探しているのですが、良
い方法はないでしょうか?

できるだけCStringは使いたくないのです。

よろしくお願いします。

tetrapod 2016/02/17(水) 18:17:46
strtoul とか。

なおぞう 2016/02/17(水) 18:50:16
[[解決]]
>tetrapod 様

ありがとうございます。

教えていただいた、cstoulをヒントに探してみたら、

TCHAR* e;
unsigned int ss = _wcstoui64(
        "FFFFFFFF",
        &e,
        16
        );

が見つかりました。unsigned long でも良いのですがこれを使おうと思います。
助かりました。
…検索が下手すぎますね。

tetrapod 2016/02/18(木) 10:03:08
そのコードコンパイル通る?ダメでしょ。 _TCHAR の扱いわかってる?

いまさらだけど _TCHAR を扱うのであれば strtoul でなくて _tcstoul だし
i64 版がよければ _tcstoui64 だよ。

16進表記文字が8桁より多く出現した場合を考えて i64 なんだろうけど
その結果を無造作に扱っているのは気になる・・・
_TCHAR と言いながら _T() を表記してないのもかなり減点。

_TCHAR* e;
unsigned __int64 ss=_tcstoui64(_T("ABCD1234"), &e, 16);

なおぞう 2016/02/18(木) 11:33:52
>tetrapod様

ご指摘、アドバイスありがとうございます。
こちらに書くときにコピーしなかったので、TEXTを書き忘れたようです。テストプログラ
ムでは、以下のように記述して確認しましたが、コンパイル通りました。

    unsigned int ss = _wcstoui64(
        TEXT("FFFFFFFF"),
        &e,
        16
        );

文字セットが「Unicode文字セット」なので、利用したい関数を見つけたら「_UNICODE が
定義されている場合」として紹介されている関数を利用するようにしているのですが、そ
の考えって正しいのでしょうか? TCHAR型の文字を使うのであれば、TCHAR.Hのルーチンを
使うのが正しいのでしょうか。この場を借りて教えていただけると助かります。


TCHAR.H のルーチン       _tcstoul
_UNICODE が定義されている場合  wcstoul

仲澤@失業者 2016/02/18(木) 14:36:31
面倒くさいことを言うようで申し訳ないのですが、厳密には

unsigned int ss = _wcstoui64(// 関数がUnicode用
        L"FFFFFFFF", // なので明示的にUnicodeを与えること
        &e,
        16
        );

ですね。

追加で、unsigned 整数を戻す文字列変換関数は、
「負」の値を意味する場合の文字列を変換できません(エラーを意味する値が戻る)。
最終的にunisigned にしたい場合でも、signed を戻す関数を
使用した方が良いそうです。

以下はtetrapodさんの大昔の発言(これ、自分も助かりました)。

http://hpcgi1.nifty.com/MADIA/Vcbbs/wwwlng.cgi?print+200506/05060078.txt

つまり_wcstoi64()の方を使った方が良いかも、というお話です。

tetrapod 2016/02/18(木) 16:00:06
TCHAR はコンパイル時にプログラム内部文字表現を変えるもの。

TCHAR をコンパイル時に char に置き換えるのが _MBCS build (Win9x で性能向上用)
TCHAR をコンパイル時に wchar_t に置き換えるのが _UNICODE build (NT/XP で性能向上)

TCHAR が char になるとき _tcstoui64 は _strtoui64 に置換される
TCHAR が wchar_t になるとき _tcstoui64 は _wcstoui64 に置換される
逆方向は無い (TCHAR->char または TCHAR->wchar_t 方向のみ置換)

というわけで、正しい組み合わせは
固定で char を使う場合 _strtoui64("ABCD" ...)
固定で wchar_t を使う場合 _wcstoui64(L"ABCD" ....)
切り替え可能に作る場合 _tcstoui64(_T("ABCD") ....)
のどれか。

_wcstoui64(_T("ABCD") ...) と書いてしまうと MBCS build で失敗してしまう
_strtoui64(_T("ABCD") ...) と書いてしまうと UNICODE build で失敗してしまう
という意味で正しくない。

_UNICODE ビルド設定でも MBCS 関数を使っていい (切り替えないで固定なら)
_MBCS ビルド設定でも UNICODE 関数を使っていい (切り替えないで固定なら)

XP 以後は Windows の内部処理が UNICODE なので、
我々末端プログラマが作るソフトの内部コードも UNICODE にしておくほうが高速です。
なので Win9x 系が死滅している今ならば
文字表現切り替え機構である UNICODE/MBCS build のことは忘れて
UNICODE 系表記 _wcstoui64(L"ABCD" ...) とするのがわかりやすいだろうと思う。

なおぞう 2016/02/18(木) 16:36:59
>仲澤@失業者 様、tetrapod様

丁寧な説明ありがとうございます。

TCHARは、コンパイル環境に合わせてchar/wchar_tに切り替えてくれるのですね。だか
ら、char型ではなく、TCHAR型を使うようにって言われているのかもしれません。

UNICODE系の場合は、 _T( ではなくて、Lを使うのですね。確かにデバッガでみると、
L"文字列”ってなっています。

古いスレッドには追加発言できません。