日本語Win10でvisual studio 2017 C++ を使っていますが、以下のコードを実行すると、
int WINAPI WinMain(HINSTANCE hCurrInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
setlocale(LC_CTYPE, ""); //<--- SJIS
char s[16];
sprintf(s, u8"取得");
return 0;
}
sprintf 内でアサーションエラーが起きます。
>>>>>>>>>
Debug Assertion Failed!
Program: D:\test\test.exe
File: minkernel\crts\ucrt\inc\corecrt_internal_stdio_output.h
Line: 1700
Expression: _format_char != '\0'
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
<<<<<<<<<
setlocale を削除するか、sprintf(s, "%s", u8"取得") とすれば直るのですが、
何故エラーが起きるのでしょうか??
"取得" という文字列はutf8にすると E58F96 E5BE97 ですが、
とくにSJISでの危険な文字と重なっているようにも思えません。
sprintf + utf8 + "取得" でアサーションエラー
Re: sprintf + utf8 + "取得" でアサーションエラー
ソースファイル (corecrt_internal_stdio_output.h) を詳細に読んだわけでないのですが、ロケールよっては?、printf 系の関数は書式文字列の整合性をチェックするようです。
u8"取得"のバイト列を Shift_JIS として解釈すると E58F(蜿) 96E5(門) BE(セ) 97 00 となります、97 はマルチバイト文字の1バイト目ですが、次が null 文字であるためエラーになっているようです。
u8"取得"のバイト列を Shift_JIS として解釈すると E58F(蜿) 96E5(門) BE(セ) 97 00 となります、97 はマルチバイト文字の1バイト目ですが、次が null 文字であるためエラーになっているようです。
Re: sprintf + utf8 + "取得" でアサーションエラー
なるほど、言われてみれば確かにそうです。
これでスッキリしました
ちなみに新規作成した、デフォルト設定状態のプロジェクトで実行したら普通に通ったので、SDK (141_xp) やライブラリの設定legacy_stdio_definitions.libなどの組み合わせによって、sprintfのチェック機構が異なるのかもしれません。
ありがとうございました
これでスッキリしました
ちなみに新規作成した、デフォルト設定状態のプロジェクトで実行したら普通に通ったので、SDK (141_xp) やライブラリの設定legacy_stdio_definitions.libなどの組み合わせによって、sprintfのチェック機構が異なるのかもしれません。
ありがとうございました
Re: sprintf + utf8 + "取得" でアサーションエラー
追記です。
上で、「新規プロジェクト作成では再現しなかった」と書きましたが、
「プロジェクト→プロパティ→C/C++→コード生成→ランタイムライブラリ」の設定を「マルチスレッドデバッグDLL」ではなく「マルチスレッドデバッグ」にすると再現しました。
DLLを使うかそうでないかで組み込みマクロの定義が変わり、ヘッダに記述されている sprintf(から呼ばれてる関数)の挙動が変わるみたいですね。
上で、「新規プロジェクト作成では再現しなかった」と書きましたが、
「プロジェクト→プロパティ→C/C++→コード生成→ランタイムライブラリ」の設定を「マルチスレッドデバッグDLL」ではなく「マルチスレッドデバッグ」にすると再現しました。
DLLを使うかそうでないかで組み込みマクロの定義が変わり、ヘッダに記述されている sprintf(から呼ばれてる関数)の挙動が変わるみたいですね。