2バイトコードの件 S-JISであれ、UTF-8であれCCS-Cの2バイトコードの扱いはコンパイル時に 勝手に7ビットに変換される部分があるようです。 例えば、”時間”は、S-JISコードで表すと0x8e,0x9e,→時、 0x8a,0xd4→間です。 これを sprintf( buff, "時間 = %d\n", p ); のように””の中に入れると、コードが勝手に7ビットに丸められることが 発生します。これは、他のマルチバイトのUTF-8やEUC-JP等と違い、コードが 特殊で2バイト目の判定が難しくなる場合があると言うことに起因するようです。 また、2バイト目に0x5C(いわゆるバックスラッシュ日本語では¥コード)があると それ以降エスケープ文字と間違ったりして漢字なら’十’のあとでおかしくなったりします。 特にprintf系の関数の場合、これらの特殊文字(¥nや¥rなど)がこのコードに含まれるとおかしくなります。 ここで、簡単な例を示します。 コンパイラはCCS-CVer5.075、マイコンはPIC18F26K20でPCH16bitでコンパイルされています。 因みに、PCMやPCHは char=unsigned int8ですが、PCDだとchar=signed int8です。 ですから、PCDでコンパイルすると違った結果になるかも知れません。 ※未確認です。 /* --------------------------------------------------------- */ const char text[] = { 0x8e, 0x9e, 0x8a, 0xd4, 0 }; // 定数で"時間"を取る char text2[10]; char text3[10]; char buff[20]; int8 wtime; wtime = 3; // 適当な数値を代入 strcpy( text2, "時間" ); // 直値”時間”をコピー strcpy( text3, text ); // 定数”時間”をコピー puts( "No1" ); sprintf(buff, "時間 = %d\r\n", wtime); puts( buff ); puts( "No2" ); sprintf(buff, "%s = %d\r\n", text2, wtime); puts( buff ); puts( "No3" ); sprintf(buff, "%s = %d\r\n", text, wtime); puts( buff ); puts( "No4" ); sprintf(buff, "%s = %d\r\n", text3, wtime); puts( buff ); puts( "No5" ); memcpy( text3, text, 5 ); sprintf(buff, "%s = %d\r\n", text3, wtime); puts( buff ); /* --------------------------------------------------------- */ これを、Teratermで受信した結果がこちらです。 なお、TeratermはS-JIS設定にしています。 /* --------------------------------------------------------- */ No1 時 ヤ = 3 No2 時 ヤ = 3 No3 時間 = 3 No4 = 3 No5 = 3 /* --------------------------------------------------------- */ テキストではわかりにくいのでバイナリで示すと以下の通りです /* --------------------------------------------------------- */ 4E 6F 31 0D 0A : No1 8E 9E 0A D4 20 3D 20 33 0D 0A : 時 ヤ = 3 4E 6F 32 0D 0A : No2 8E 9E 0A D4 20 3D 20 33 0D 0A : 時 ヤ = 3 4E 6F 33 0D 0A : No3 8E 9E 8A D4 20 3D 20 33 0D 0A : 時間 = 3 4E 6F 34 0D 0A : No4 20 3D 20 33 0D 0A 0D 0A : = 3 4E 6F 35 0D 0A : No5 20 3D 20 33 0D 0A 0D 0A : = 3 /* --------------------------------------------------------- */ つまり、No3以外はすべて文字が化けていて、定数で取った const char text[] = { 0x8e, 0x9e, 0x8a, 0xd4, 0 }; をそのまま sprintfに渡せばspintfはそれをそのまま%sに入れているようです。 この定数textをstrcpyやmemcpyで別のバッファtext2やtext3に入れると化けます。 勿論、strcpyに直値で”時間”と入れても同じです。 つまり、CCS-Cでは、2バイトコードの扱いに非常に不備があると言う訳ではありません。 もともと英語圏のプログラムなので2バイトコードの意識がありませんのでこのような結果になります。 これを避けるには、定数として漢字コードを持つしか方法がありません。 少なくとも、私共の経験でもASCIIコード以外はまず駄目です。 あとは、printfなどをライブラリに依存せずに自力で構築することですが それはめんどくさいし、せっかくのコンパイラのライブラリがあるので定数でそれを利用します。 これらの漢字コードをテーブルに埋め込む場合に、CCS-IDEの”Data to C”といったツールを利用するのが便利です。 Toolsメニューから”Data to C”を選択します。 最初にテキストエディタなどで必要な漢字リストを作成します。 例えば Kanji.txtというファイルに  時間  温度  数値  定数  などなど と必要な文字を入力して保存しておきます。この時、エディタのコード体系をS-JISにしておくことです。 ”Data to C”のファイル入力にこのKanji.txtを指定し、 Binary、int8として出力ファイルにKanji.c等適当なファイル名を 入力して、CONST,int8としてCreatボタンをクリックするとICEのエディタに Kanji.cが表示されます。この例の場合なら const int8 table[34] = { 0x8E,0x9E,0x8A,0xD4,0x0D,0x0A,0x89,0xB7,0x93,0x78,0x0D,0x0A,0x90,0x94,0x92,0x6C, 0x0D,0x0A,0x92,0xE8,0x90,0x94,0x0D,0x0A,0x82,0xC8,0x82,0xC7,0x82,0xC8,0x82,0xC7, 0x0D,0x0A}; のようになりますので、これを編集して const char JIKAN_STR[] = { 0x8E,0x9E,0x8A,0xD4,0 }; const char ONDO_STR[] = { 0x89,0xB7,0x93,0x78,0 }; const char SUUCHI_STR[] = { 0x90,0x94,0x92,0x6C,0 }; const char TEISU_STR[] = { 0x92,0xE8,0x90,0x94,0 }; const char NADONADO_STR[] = { 0x82,0xC8,0x82,0xC7,0x82,0xC8,0x82,0xC7,0 }; のようにしてprintf関数の%sパラメーターに与えます。 おそらく、これで問題なく動作できると思います。 いちいちS-JISコード表から漢字を拾ってきて埋め込むより遙かに速く文字コードを作成できます。 残念ながら、私共はこの方法でしか漢字をターミナルに出力する方法を知りません。 キャラクタ表示タイプのLCD(16x2とか20x4とか)にカナを表示する場合も このように半角のカナコードをテーブルにとって出力しないと、 char text[] = { "アイウエオ" };としたり、sprintf(buff,"%s","アイウエオ");などとすると大抵、失敗します。 要するに、漢字コードを1バイトずつ定数にとって、それをprintfやputs関数に渡してやるとうまくいくようです。 つまり、エディタなどのコード体系、受信するターミナルソフトのコード体系などが一致していませんとおかしな事になります。 ご参考になりましたら幸いです。