cmd.exe はどのエンコード/コード ページを使用していますか? 質問する

cmd.exe はどのエンコード/コード ページを使用していますか? 質問する

Windows で開くとcmd.exe、どのようなエンコードが使用されますか?

現在使用されているエンコーディングを確認するにはどうすればいいですか?
地域設定に依存しますか、それとも確認すべき環境変数がありますか?

特定のエンコードでファイルを入力するとどうなりますか? 文字化けすることもあれば (エンコードが間違っているため)、うまく動作することもあります。
しかし、何が起こっているのか分からない限り、何も信用できません。誰か説明してもらえませんか?

ベストアンサー1

はい、イライラします。type他のプログラムでは意味不明な文字が印刷されることもありますし、印刷されないこともあります。

まず、Unicode文字は現在のコンソールフォントに文字が含まれている場合したがって、デフォルトのラスター フォントの代わりに、Lucida Console などの TrueType フォントを使用します。

ただし、コンソールのフォントに表示しようとしている文字が含まれていない場合は、意味不明な文字ではなく疑問符が表示されます。意味不明な文字が表示される場合は、フォント設定以外の問題も発生しています。

プログラムが のような標準 C ライブラリ I/O 関数を使用する場合printfプログラムの出力エンコーディングはコンソールの出力エンコーディング と一致している必要があります。一致していない場合は、意味不明な結果になります。 は、chcp現在のコード ページを表示および設定します。標準 C ライブラリ I/O 関数を使用したすべての出力は、 によって表示されるコード ページにあるかのように扱われますchcp

プログラムの出力エンコーディングをコンソールの出力エンコーディングと一致させるには、次の 2 つの方法があります。

  • プログラムはコンソールの現在のコードページを次chcpのように取得できる。GetConsoleOutputCP、そのエンコーディングで出力するように設定するか、

  • chcpあなたまたはプログラムは、またはを使用してコンソールの現在のコードページを設定できます。SetConsoleOutputCPプログラムのデフォルトの出力エンコーディングと一致させます。

ただし、Win32 APIを使用するプログラムは、UTF-16LE文字列をコンソールに直接書き込むことができます。WriteConsoleWこれは、コードページを設定せずに正しい出力を得る唯一の方法です。また、その関数を使用する場合でも、文字列がUTF-16LEエンコーディングでない場合は、Win32プログラムは正しいコードページを渡す必要があります。MultiByteToWideCharまた、WriteConsoleWプログラムの出力がリダイレクトされている場合は動作しません。その場合は、さらに調整が必要になります。

type各ファイルの先頭にUTF-16LEがあるかどうかをチェックするので、時々は機能します。バイトオーダーマーク (BOM)、つまりバイト です0xFF 0xFE。このようなマークが見つかると、WriteConsoleW現在のコードページに関係なく、 を使用してファイル内の Unicode 文字を表示します。ただし、typeUTF-16LE BOM のないファイルを する場合、または を呼び出さないコマンドで非 ASCII 文字を使用する場合はWriteConsoleW、コンソールのコードページとプログラムの出力エンコーディングを互いに一致するように設定する必要があります。


どうすればこれを知ることができますか?

以下は Unicode 文字を含むテスト ファイルです。

ASCII     abcde xyz
German    äöü ÄÖÜ ß
Polish    ąęźżńł
Russian   абвгдеж эюя
CJK       你好

これは、さまざまな Unicode エンコードでテスト ファイルを印刷する Java プログラムです。任意のプログラミング言語で記述できますが、ASCII 文字またはエンコードされたバイトのみを に印刷しますstdout

import java.io.*;

public class Foo {

    private static final String BOM = "\ufeff";
    private static final String TEST_STRING
        = "ASCII     abcde xyz\n"
        + "German    äöü ÄÖÜ ß\n"
        + "Polish    ąęźżńł\n"
        + "Russian   абвгдеж эюя\n"
        + "CJK       你好\n";

    public static void main(String[] args)
        throws Exception
    {
        String[] encodings = new String[] {
            "UTF-8", "UTF-16LE", "UTF-16BE", "UTF-32LE", "UTF-32BE" };

        for (String encoding: encodings) {
            System.out.println("== " + encoding);

            for (boolean writeBom: new Boolean[] {false, true}) {
                System.out.println(writeBom ? "= bom" : "= no bom");

                String output = (writeBom ? BOM : "") + TEST_STRING;
                byte[] bytes = output.getBytes(encoding);
                System.out.write(bytes);
                FileOutputStream out = new FileOutputStream("uc-test-"
                    + encoding + (writeBom ? "-bom.txt" : "-nobom.txt"));
                out.write(bytes);
                out.close();
            }
        }
    }
}

デフォルトのコードページでの出力ですか?まったくのゴミです!

Z:\andrew\projects\sx\1259084>chcp
Active code page: 850

Z:\andrew\projects\sx\1259084>java Foo
== UTF-8
= no bom
ASCII     abcde xyz
German    ├ñ├Â├╝ ├ä├û├£ ├ƒ
Polish    ąęźżńł
Russian   ð░ð▒ð▓ð│ð┤ðÁð ÐìÐÄÐÅ
CJK       õ¢áÕÑ¢
= bom
´╗┐ASCII     abcde xyz
German    ├ñ├Â├╝ ├ä├û├£ ├ƒ
Polish    ąęźżńł
Russian   ð░ð▒ð▓ð│ð┤ðÁð ÐìÐÄÐÅ
CJK       õ¢áÕÑ¢
== UTF-16LE
= no bom
A S C I I           a b c d e   x y z
 G e r m a n         õ ÷ ³   ─ Í ▄   ▀
 P o l i s h         ♣☺↓☺z☺|☺D☺B☺
 R u s s i a n       0♦1♦2♦3♦4♦5♦6♦  M♦N♦O♦
 C J K               `O}Y
 = bom
 ■A S C I I           a b c d e   x y z
 G e r m a n         õ ÷ ³   ─ Í ▄   ▀
 P o l i s h         ♣☺↓☺z☺|☺D☺B☺
 R u s s i a n       0♦1♦2♦3♦4♦5♦6♦  M♦N♦O♦
 C J K               `O}Y
 == UTF-16BE
= no bom
 A S C I I           a b c d e   x y z
 G e r m a n         õ ÷ ³   ─ Í ▄   ▀
 P o l i s h        ☺♣☺↓☺z☺|☺D☺B
 R u s s i a n      ♦0♦1♦2♦3♦4♦5♦6  ♦M♦N♦O
 C J K              O`Y}
= bom
■  A S C I I           a b c d e   x y z
 G e r m a n         õ ÷ ³   ─ Í ▄   ▀
 P o l i s h        ☺♣☺↓☺z☺|☺D☺B
 R u s s i a n      ♦0♦1♦2♦3♦4♦5♦6  ♦M♦N♦O
 C J K              O`Y}
== UTF-32LE
= no bom
A   S   C   I   I                       a   b   c   d   e       x   y   z
   G   e   r   m   a   n                   õ   ÷   ³       ─   Í   ▄       ▀
   P   o   l   i   s   h                   ♣☺  ↓☺  z☺  |☺  D☺  B☺
   R   u   s   s   i   a   n               0♦  1♦  2♦  3♦  4♦  5♦  6♦      M♦  N
♦  O♦
   C   J   K                               `O  }Y
   = bom
 ■  A   S   C   I   I                       a   b   c   d   e       x   y   z

   G   e   r   m   a   n                   õ   ÷   ³       ─   Í   ▄       ▀
   P   o   l   i   s   h                   ♣☺  ↓☺  z☺  |☺  D☺  B☺
   R   u   s   s   i   a   n               0♦  1♦  2♦  3♦  4♦  5♦  6♦      M♦  N
♦  O♦
   C   J   K                               `O  }Y
   == UTF-32BE
= no bom
   A   S   C   I   I                       a   b   c   d   e       x   y   z
   G   e   r   m   a   n                   õ   ÷   ³       ─   Í   ▄       ▀
   P   o   l   i   s   h                  ☺♣  ☺↓  ☺z  ☺|  ☺D  ☺B
   R   u   s   s   i   a   n              ♦0  ♦1  ♦2  ♦3  ♦4  ♦5  ♦6      ♦M  ♦N
  ♦O
   C   J   K                              O`  Y}
= bom
  ■    A   S   C   I   I                       a   b   c   d   e       x   y   z

   G   e   r   m   a   n                   õ   ÷   ³       ─   Í   ▄       ▀
   P   o   l   i   s   h                  ☺♣  ☺↓  ☺z  ☺|  ☺D  ☺B
   R   u   s   s   i   a   n              ♦0  ♦1  ♦2  ♦3  ♦4  ♦5  ♦6      ♦M  ♦N
  ♦O
   C   J   K                              O`  Y}

しかし、type保存されたファイルの場合はどうなるでしょうか? コンソールに出力されたバイトとまったく同じバイトが含まれています。

Z:\andrew\projects\sx\1259084>type *.txt

uc-test-UTF-16BE-bom.txt


■  A S C I I           a b c d e   x y z
 G e r m a n         õ ÷ ³   ─ Í ▄   ▀
 P o l i s h        ☺♣☺↓☺z☺|☺D☺B
 R u s s i a n      ♦0♦1♦2♦3♦4♦5♦6  ♦M♦N♦O
 C J K              O`Y}

uc-test-UTF-16BE-nobom.txt


 A S C I I           a b c d e   x y z
 G e r m a n         õ ÷ ³   ─ Í ▄   ▀
 P o l i s h        ☺♣☺↓☺z☺|☺D☺B
 R u s s i a n      ♦0♦1♦2♦3♦4♦5♦6  ♦M♦N♦O
 C J K              O`Y}

uc-test-UTF-16LE-bom.txt


ASCII     abcde xyz
German    äöü ÄÖÜ ß
Polish    ąęźżńł
Russian   абвгдеж эюя
CJK       你好

uc-test-UTF-16LE-nobom.txt


A S C I I           a b c d e   x y z
 G e r m a n         õ ÷ ³   ─ Í ▄   ▀
 P o l i s h         ♣☺↓☺z☺|☺D☺B☺
 R u s s i a n       0♦1♦2♦3♦4♦5♦6♦  M♦N♦O♦
 C J K               `O}Y

uc-test-UTF-32BE-bom.txt


  ■    A   S   C   I   I                       a   b   c   d   e       x   y   z

   G   e   r   m   a   n                   õ   ÷   ³       ─   Í   ▄       ▀
   P   o   l   i   s   h                  ☺♣  ☺↓  ☺z  ☺|  ☺D  ☺B
   R   u   s   s   i   a   n              ♦0  ♦1  ♦2  ♦3  ♦4  ♦5  ♦6      ♦M  ♦N
  ♦O
   C   J   K                              O`  Y}

uc-test-UTF-32BE-nobom.txt


   A   S   C   I   I                       a   b   c   d   e       x   y   z
   G   e   r   m   a   n                   õ   ÷   ³       ─   Í   ▄       ▀
   P   o   l   i   s   h                  ☺♣  ☺↓  ☺z  ☺|  ☺D  ☺B
   R   u   s   s   i   a   n              ♦0  ♦1  ♦2  ♦3  ♦4  ♦5  ♦6      ♦M  ♦N
  ♦O
   C   J   K                              O`  Y}

uc-test-UTF-32LE-bom.txt


 A S C I I           a b c d e   x y z
 G e r m a n         ä ö ü   Ä Ö Ü   ß
 P o l i s h         ą ę ź ż ń ł
 R u s s i a n       а б в г д е ж   э ю я
 C J K               你 好

uc-test-UTF-32LE-nobom.txt


A   S   C   I   I                       a   b   c   d   e       x   y   z
   G   e   r   m   a   n                   õ   ÷   ³       ─   Í   ▄       ▀
   P   o   l   i   s   h                   ♣☺  ↓☺  z☺  |☺  D☺  B☺
   R   u   s   s   i   a   n               0♦  1♦  2♦  3♦  4♦  5♦  6♦      M♦  N
♦  O♦
   C   J   K                               `O  }Y

uc-test-UTF-8-bom.txt


´╗┐ASCII     abcde xyz
German    ├ñ├Â├╝ ├ä├û├£ ├ƒ
Polish    ąęźżńł
Russian   ð░ð▒ð▓ð│ð┤ðÁð ÐìÐÄÐÅ
CJK       õ¢áÕÑ¢

uc-test-UTF-8-nobom.txt


ASCII     abcde xyz
German    ├ñ├Â├╝ ├ä├û├£ ├ƒ
Polish    ąęźżńł
Russian   ð░ð▒ð▓ð│ð┤ðÁð ÐìÐÄÐÅ
CJK       õ¢áÕÑ¢

機能するのは、 を介してコンソールに出力される、BOM 付きの UTF-16LE ファイルだけですtype

typeファイルを印刷する以外の方法を使用すると、ゴミが発生します。

Z:\andrew\projects\sx\1259084>copy uc-test-UTF-16LE-bom.txt CON
 ■A S C I I           a b c d e   x y z
 G e r m a n         õ ÷ ³   ─ Í ▄   ▀
 P o l i s h         ♣☺↓☺z☺|☺D☺B☺
 R u s s i a n       0♦1♦2♦3♦4♦5♦6♦  M♦N♦O♦
 C J K               `O}Y
         1 file(s) copied.

copy CONUnicode が正しく表示されないという事実から、typeコマンドにはファイルの先頭にある UTF-16LE BOM を検出し、特別な Windows API を使用してそれを印刷するロジックがあると結論付けることができます。

ファイルの出力cmd.exe時にデバッガーで開くと、これを確認できます。type

ここに画像の説明を入力してください

typeファイルを開いた後、 の BOM (つまり、リトルエンディアンの0xFEFFバイト)をチェックし、そのような BOM がある場合は内部フラグを設定します。このフラグは後で を呼び出すかどうかを決定するためにチェックされます。0xFF 0xFEtypefOutputUnicodeWriteConsoleW

しかし、これは Unicode を出力する唯一の方法でありtype、BOM があり UTF-16LE 形式のファイルに対してのみ有効です。その他のすべてのファイル、およびコンソール出力を処理するための特別なコードを持たないプログラムの場合、ファイルは現在のコード ページに従って解釈され、意味不明な文字として表示される可能性があります。

type次のように、独自のプログラムでコンソールに Unicode を出力する方法をエミュレートできます。

#include <stdio.h>
#define UNICODE
#include <windows.h>

static LPCSTR lpcsTest =
    "ASCII     abcde xyz\n"
    "German    äöü ÄÖÜ ß\n"
    "Polish    ąęźżńł\n"
    "Russian   абвгдеж эюя\n"
    "CJK       你好\n";

int main() {
    int n;
    wchar_t buf[1024];

    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

    n = MultiByteToWideChar(CP_UTF8, 0,
            lpcsTest, strlen(lpcsTest),
            buf, sizeof(buf));

    WriteConsole(hConsole, buf, n, &n, NULL);

    return 0;
}

このプログラムは、デフォルトのコードページを使用して Windows コンソールに Unicode を印刷するために機能します。


サンプル Java プログラムでは、コードページを手動で設定することで、多少は正しい出力を得ることができますが、出力は奇妙な形で乱れてしまいます。

Z:\andrew\projects\sx\1259084>chcp 65001
Active code page: 65001

Z:\andrew\projects\sx\1259084>java Foo
== UTF-8
= no bom
ASCII     abcde xyz
German    äöü ÄÖÜ ß
Polish    ąęźżńł
Russian   абвгдеж эюя
CJK       你好
ж эюя
CJK       你好
 你好
= bom
ASCII     abcde xyz
German    äöü ÄÖÜ ß
Polish    ąęźżńł
Russian   абвгдеж эюя
CJK       你好
еж эюя
CJK       你好
  你好
== UTF-16LE
= no bom
A S C I I           a b c d e   x y z

ただし、Unicode UTF-8 コードページを設定する C プログラム:

#include <stdio.h>
#include <windows.h>

int main() {
    int c, n;
    UINT oldCodePage;
    char buf[1024];

    oldCodePage = GetConsoleOutputCP();
    if (!SetConsoleOutputCP(65001)) {
        printf("error\n");
    }

    freopen("uc-test-UTF-8-nobom.txt", "rb", stdin);
    n = fread(buf, sizeof(buf[0]), sizeof(buf), stdin);
    fwrite(buf, sizeof(buf[0]), n, stdout);

    SetConsoleOutputCP(oldCodePage);

    return 0;
}

正しい出力が得られます:

Z:\andrew\projects\sx\1259084>.\test
ASCII     abcde xyz
German    äöü ÄÖÜ ß
Polish    ąęźżńł
Russian   абвгдеж эюя
CJK       你好

この話の教訓は?

  • type現在のコードページに関係なく、BOM付きのUTF-16LEファイルを印刷できます。
  • Win32 プログラムは、 を使用して、コンソールに Unicode を出力するようにプログラムできますWriteConsoleW
  • コードページを設定し、それに応じて出力エンコーディングを調整する他のプログラムは、プログラムの開始時のコードページに関係なく、コンソールにUnicodeを出力できます。
  • その他すべてについては、 をいじる必要がありchcp、おそらく依然として奇妙な出力が得られるでしょう。

おすすめ記事