マルチバイト文字 解答ページ | Programming Place Plus C言語編 第46章

トップページC言語編第46章

問題① 🔗

問題① Shift_JIS において、「表」という文字が 0x5c を含んでいることを、バイナリエディタを使って確認してください。


適当なテキストエディタを使って、「表」とだけ書かれたテキストファイルを作成します。 これを、バイナリエディタに読み込ませれば確認できます。

テキストエディタでファイルを保存する際には、Shift_JIS で保存するように指定しなければならないかもしれません。この辺りは、お使いのテキストエディタのマニュアルを参照するなどして確認してください。

Windows付属のメモ帳の場合、文字コードを「ANSI」に指定します。

問題② 🔗

問題② マルチバイト文字に Shift_JIS を使う場合、以下の実行結果がいくつになるか答えてください。

printf("%zu\n", sizeof('あ'));
printf("%zu\n", sizeof("ABCABC"));
printf("%zu\n", strlen("ABCABC"));


まず、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)
{
    printf("%zu\n", sizeof('あ'));
    printf("%zu\n", sizeof("ABCABC"));
    printf("%zu\n", strlen("ABCABC"));
}

実行結果:

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) {
        fputs("ロケールの設定に失敗しました。\n", stderr);
        return 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) {
            fputs("不正な文字を含んでいます。\n", stderr);
            return EXIT_FAILURE;
        }

        // 文字の大きさ分だけ、出力用のバッファへコピー
        memcpy(&output_buf[STRING_SIZE - i - len - 1], &str[i], len);

        // 文字の大きさ文だけ、先へ進める
        i += len;
    }

    output_buf[STRING_SIZE - 1] = '\0';
    puts(output_buf);
}

実行結果:

在混の IICSA と語本日

1文字の大きさが分からないので、先頭から1文字ずつ mblen関数を使って調べる必要があります。その文字が使っているバイト数を得たら、その大きさ分だけ、出力用バッファの後ろの方へコピーしています。



参考リンク 🔗


更新履歴 🔗

≪さらに古い更新履歴≫

 全面的に文章を見直し、修正を行った。

 文章中の表記を統一(bit、Byte -> ビット、バイト)

 Shift_JIS と表記されるべき箇所が、utf-8 になってしまっていたのを修正。

 setlocale関数の LC_CTYPE の指定を修正。

 問題②の解説から、第20章へのリンクを張った。

 新規作成。



第46章のメインページへ

C言語編のトップページへ

Programming Place Plus のトップページへ



はてなブックマーク に保存 Pocket に保存 Facebook でシェア
X で ポストフォロー LINE で送る noteで書く
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー
先頭へ戻る