文字列内の原因不明の文字化け
テクニカル・ノート 96004
アーキテクチャ:
All
コンポーネント:
general
更新日:
2018/08/26 3:50
はじめに
printfまたはsprintfで出力された文字列に、文字化けした意味不明の文字が含まれている場合がある。
解決方法
sprintf/printfで使用されている書式文字列を入念にチェックしてください。
また、strncatの使い方が間違っていないかチェックしてください(下記の例を参照)。
背景
文字化けが発生する原因はいくつもあります。
- %sで使用される文字列がヌル文字('\0')で終了していない。この場合、その前にstrncpyが使用された可能性があります(strncpyでは、出力先の文字列が必ずしもヌル文字で締めくくられるとは限りません)。
- %sと%dを混同したために、ヌル文字が抜けている。例えば、printf("%s", 2000)と記述した場合、アドレス0x7D0にあるものが出力されます。
- sprintfに渡す引数の数が、書式文字列の数と一致していない。以下の例について考えてみましょう。
const char *formatstr = "Test1 %c Test2 %c\n"; printf(formatstr, 'A');
printf関数(またはsprintf関数)に渡す引数の数が、書式文字列の数と一致していません(書式文字列と比べて引数の数が足りません)。書式文字列は動的に解釈されるため、コンパイラでは警告が表示されません。この例では、メモリに何が格納されているかによって異なりますが、例えば次のような文字列が出力されます: "Test1 A Test2 @"
初期化されていないRAMを参照しようとしているかどうかを判断するには、特定のパターン(例えば'0xAA')でRAMを埋めます。文字化けした文字が'0xAA'に変わった場合、アプリケーション内のどこかで文字列処理が間違っています(そうでない場合は、その文字は別のデータエリアまたはコードエリアから取得された可能性があります)。
もう一つの方法は、文字列を使用する前に、出力先の文字列を'\0'で完全に初期化する方法です。なお、この方法はあくまでテストとして行ってください。この方法で現象が発生しなくなる場合があっても、問題は残ったままです。
全ての製品名は、それぞれの所有者の商標または登録商標です。