マルチバイト文字 解答ページ | Programming Place Plus C言語編 第46章
Programming Place Plus トップページ – C言語編 – 第46章
問題① Shift_JIS において、「表」という文字が 0x5c を含んでいることを、バイナリエディタを使って確認してください。
適当なテキストエディタを使って、「表」とだけ書かれたテキストファイルを作成します。 これを、バイナリエディタに読み込ませれば確認できます。
テキストエディタでファイルを保存する際には、Shift_JIS で保存するように指定しなければならないかもしれません。この辺りは、お使いのテキストエディタのマニュアルを参照するなどして確認してください。
Windows付属のメモ帳の場合、文字コードを「ANSI」に指定します。
問題② マルチバイト文字に Shift_JIS を使う場合、以下の実行結果がいくつになるか答えてください。
( "%zu\n", sizeof('あ') );
printf( "%zu\n", sizeof("ABCABC") );
printf( "%zu\n", strlen("ABCABC") ); printf
まず、1つ目はやや引っ掛けです。C言語において、‘A’ のような文字リテラルは、int型とみなされるため、sizeof(int) をしているのに他なりません(第19章参照)。そのため、32ビット環境であれば、結果は 4 になります。
2つ目はどうでしょう。 ASCIIコードで表現できる ‘A’、‘B’、‘C’ は 1バイト、それ以外の文字は 2バイトが必要です。 そのため、(1 * 3 + 2 * 3) で 9バイト。 ここにヌル文字の分が加わるので、結果は 10 になります。
3つ目は、文字数ですが、strlen関数は、1バイトが 1文字である前提なので、“ABC” の部分を 6文字であると誤認識します。結果は 9 です。
#include <stdio.h>
#include <string.h>
int main(void)
{
( "%zu\n", sizeof('あ') );
printf( "%zu\n", sizeof("ABCABC") );
printf( "%zu\n", strlen("ABCABC") );
printf}
実行結果
4
10
9
問題③ ASCIIコードで表現できる文字と、できない文字とが混在した Shift_JIS の文字列を、逆順にして出力するプログラムを作成してください。
たとえば、次のようになります。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#define STRING "日本語と ASCII の混在"
#define STRING_SIZE sizeof(STRING)
int main(void)
{
const char* str = STRING;
if( setlocale( LC_CTYPE, "" ) == NULL ){
( "ロケールの設定に失敗しました。\n", stderr );
fputsreturn EXIT_FAILURE;
}
char output_buf[STRING_SIZE];
int i = 0;
while( str[i] != '\0' ){
// 1文字の大きさを取得
int len = mblen( &str[i], MB_CUR_MAX );
if( len < 0 ){
( "不正な文字を含んでいます。\n", stderr );
fputsreturn EXIT_FAILURE;
}
// 文字の大きさ分だけ、出力用のバッファへコピー
( &output_buf[STRING_SIZE - i - len - 1], &str[i], len );
memcpy
// 文字の大きさ文だけ、先へ進める
+= len;
i }
[STRING_SIZE - 1] = '\0';
output_buf( output_buf );
puts}
実行結果
在混の IICSA と語本日
1文字の大きさが分からないので、先頭から1文字ずつ mblen関数を使って調べる必要があります。その文字が使っているバイト数を得たら、その大きさ分だけ、出力用バッファの後ろの方へコピーしています。
return 0;
を削除(C言語編全体でのコードの統一)’2018/3/21 全面的に文章を見直し、修正を行った。
’2018/2/21 文章中の表記を統一(bit、Byte -> ビット、バイト)
≪さらに古い更新履歴を展開する≫
Programming Place Plus のトップページへ