cmd.exe ใช้หน้าเข้ารหัสหรือรหัสอะไร


271

เมื่อฉันเปิด cmd.exe ใน Windows มันใช้การเข้ารหัสแบบใด

ฉันจะตรวจสอบการเข้ารหัสที่ใช้อยู่ได้อย่างไร มันขึ้นอยู่กับการตั้งค่าภูมิภาคของฉันหรือมีตัวแปรสภาพแวดล้อมใด ๆ ที่ต้องตรวจสอบหรือไม่

จะเกิดอะไรขึ้นเมื่อคุณพิมพ์ไฟล์ด้วยการเข้ารหัสที่แน่นอน? บางครั้งฉันได้รับอักขระที่อ่านไม่ออก (ใช้การเข้ารหัสที่ไม่ถูกต้อง) และบางครั้งก็เป็นงาน อย่างไรก็ตามฉันไม่เชื่ออะไรตราบใดที่ฉันไม่รู้ว่าเกิดอะไรขึ้น มีใครอธิบายได้บ้าง

คำตอบ:


389

ใช่มันน่าหงุดหงิด - บางครั้งtypeโปรแกรมอื่นก็พิมพ์ซึ่งพูดพล่อยๆและบางครั้งก็ทำไม่ได้

แรกของทุกตัวอักษร Unicode จะแสดงเฉพาะถ้าตัวอักษรคอนโซลปัจจุบันมีตัวละคร ดังนั้นใช้ฟอนต์ TrueType เช่น Lucida Console แทนฟอนต์ Raster เริ่มต้น

แต่ถ้าฟอนต์คอนโซลไม่มีอักขระที่คุณพยายามแสดงคุณจะเห็นเครื่องหมายคำถามแทนซึ่งพูดไม่ชัด เมื่อคุณพูดพล่อยๆมีเกิดขึ้นมากกว่าเพียงแค่การตั้งค่าแบบอักษร

เมื่อโปรแกรมใช้ฟังก์ชั่น C-ห้องสมุด I / O มาตรฐานเช่นprintf, การเข้ารหัสเอาท์พุทของโปรแกรมจะต้องตรงกับการเข้ารหัสการส่งออกของคอนโซลหรือคุณจะได้รับการพูดพล่อยๆ chcpแสดงและตั้งค่าเพจรหัสปัจจุบัน การส่งออกทั้งหมดโดยใช้มาตรฐาน C-ห้องสมุดฟังก์ชั่น I / O chcpจะถือว่าเป็นถ้ามันอยู่ในเพจที่แสดงโดย

การจับคู่การเข้ารหัสเอาต์พุตของโปรแกรมกับการเข้ารหัสเอาต์พุตคอนโซลสามารถทำได้สองวิธี:

  • โปรแกรมสามารถรับ codepage ปัจจุบันของคอนโซลโดยใช้chcpหรือ GetConsoleOutputCPและกำหนดค่าตัวเองเป็นเอาต์พุตในการเข้ารหัสนั้นหรือ

  • คุณหรือโปรแกรมสามารถตั้งค่าเพจรหัสปัจจุบันของคอนโซลโดยใช้chcpหรือ SetConsoleOutputCPเพื่อให้ตรงกับการเข้ารหัสเอาต์พุตเริ่มต้นของโปรแกรม

แต่โปรแกรมที่ใช้ Win32 API ที่สามารถเขียน UTF-16LE WriteConsoleWสตริงโดยตรงไปยังคอนโซลด้วย นี่เป็นวิธีเดียวในการรับเอาต์พุตที่ถูกต้องโดยไม่ต้องตั้งค่าเพจรหัส และแม้กระทั่งเมื่อใช้ฟังก์ชั่นว่าถ้าสตริงไม่ได้อยู่ใน UTF-16LE การเข้ารหัสจะเริ่มต้นด้วยโปรแกรม Win32 MultiByteToWideCharต้องผ่านเพจรหัสที่ถูกต้อง นอกจากนี้WriteConsoleWจะไม่ทำงานหากเอาต์พุตของโปรแกรมถูกเปลี่ยนเส้นทาง เล่นซอเป็นสิ่งจำเป็นในกรณีนี้

typeการทำงานบางส่วนของเวลาเพราะมันจะตรวจสอบจุดเริ่มต้นของแต่ละไฟล์สำหรับ UTF-16LE มาร์คไบต์สั่งซื้อ (BOM)0xFF 0xFEคือไบต์ หากพบเครื่องหมายดังกล่าวจะแสดงอักขระ Unicode ในไฟล์โดยใช้โดยWriteConsoleW ไม่คำนึงถึงเพจรหัสปัจจุบัน แต่เมื่อนำtypeไฟล์ใด ๆ ที่ไม่มี UTF-16LE BOM หรือใช้อักขระที่ไม่ใช่ ASCII กับคำสั่งใด ๆ ที่ไม่ได้เรียกWriteConsoleW- คุณจะต้องตั้งค่า codepage ของคอนโซลและการเข้ารหัสเอาต์พุตของโปรแกรมเพื่อให้เข้ากัน


เราจะทราบได้อย่างไร?

นี่คือไฟล์ทดสอบที่มีอักขระ Unicode:

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

นี่คือโปรแกรม Java เพื่อพิมพ์ไฟล์ทดสอบในการเข้ารหัส Unicode ที่แตกต่างกัน มันอาจเป็นภาษาการเขียนโปรแกรมใด ๆ มันพิมพ์อักขระ 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       õ¢áÕÑ¢

เพียงสิ่งที่ผลงานเป็นไฟล์ UTF-16LE กับ BOM 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 CONว่าไม่ได้แสดง Unicode อย่างถูกต้องเราสามารถสรุปได้ว่าtypeคำสั่งนั้นมีตรรกะในการตรวจจับ UTF-16LE BOM ที่จุดเริ่มต้นของไฟล์และใช้ Windows API พิเศษเพื่อพิมพ์

เราสามารถเห็นสิ่งนี้ได้โดยการเปิดcmd.exeในตัวดีบั๊กเมื่อมันดับtype ไฟล์:

ป้อนคำอธิบายรูปภาพที่นี่

หลังจากtypeเปิดไฟล์มันจะตรวจสอบ BOM ของ0xFEFF- เป็นไบต์ 0xFF 0xFEในหน่วยเล็ก - และถ้ามี BOM เช่นนั้นให้typeตั้งfOutputUnicodeค่าสถานะภายใน WriteConsoleWธงนี้มีการตรวจสอบในภายหลังเพื่อตัดสินใจว่าจะโทร

แต่นั่นเป็นวิธีเดียวในการรับtypeเอาต์พุต Unicode และเฉพาะไฟล์ที่มี BOM และอยู่ใน UTF-16LE สำหรับไฟล์อื่น ๆ ทั้งหมดและสำหรับโปรแกรมที่ไม่มีรหัสพิเศษสำหรับจัดการเอาต์พุตคอนโซลไฟล์ของคุณจะถูกตีความตามเพจรหัสปัจจุบัน

คุณสามารถจำลองว่าtypeUnicode ส่งออกไปยังคอนโซลในโปรแกรมของคุณได้อย่างไร:

#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;
}

โปรแกรมนี้ทำงานสำหรับการพิมพ์ Unicode บนคอนโซล Windows โดยใช้เพจรหัสเริ่มต้น


สำหรับตัวอย่างโปรแกรม 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
…

อย่างไรก็ตามโปรแกรม C ที่ตั้งค่าเพจรหัส Unicode UTF-8:

#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 สามารถพิมพ์ไฟล์ UTF-16LE ด้วย BOM โดยไม่คำนึงถึงเพจรหัสปัจจุบันของคุณ
  • โปรแกรม Win32 สามารถตั้งโปรแกรมให้ส่งออกไปยังคอนโซล Unicode WriteConsoleWที่ใช้
  • โปรแกรมอื่น ๆ ที่ตั้งค่าเพจรหัสและปรับการเข้ารหัสผลลัพธ์สามารถพิมพ์ Unicode บนคอนโซลโดยไม่คำนึงว่าเพจรหัสเป็นอย่างไรเมื่อโปรแกรมเริ่มทำงาน
  • สำหรับทุกสิ่งที่คุณจะต้องยุ่งกับchcpและอาจจะยังคงได้รับผลแปลก

73
โอ้โหนี่เป็นคำตอบที่ละเอียดที่สุดที่ฉันเคยเห็นใน SO เครดิตเพิ่มเติมสำหรับการพิมพ์การแยกส่วนและความสามารถหลายภาษา! สวยจังเลย!
airstrike

2
อาจต้องการศึกษาส่วนขยายเฉพาะของ Microsoft _setmode (_fileno (stdout), _O_U16TEXT) ซึ่งเปิดตัวใน VS2008 ดูstackoverflow.com/a/9051543และstackoverflow.com/a/12015918และmsdn.microsoft.com/en-us/library/tw4k6df8(v=vs.90).aspxนอกจากความแตกต่างของพอร์ตที่ชัดเจนระหว่าง _setmode () และ SetConsoleOutputCP () อาจมีรายละเอียดปลีกย่อยและผลข้างเคียงอื่น ๆ ที่ซ่อนอยู่ในทั้งสองวิธีที่ไม่เข้าใจอย่างสมบูรณ์ในการมองแวบแรก หาก andrewdotn สามารถอัปเดตคำตอบของเขาด้วยการสังเกตใด ๆ เกี่ยวกับ _setmode (fd, _O_U16TEXT) นั่นจะดีมาก
JasDev

13
แม้ว่านี่จะเป็นคำตอบที่ยอดเยี่ยม แต่ก็ทำให้เข้าใจผิดว่าคอนโซลรองรับ UTF-16 มัน จำกัด อยู่ที่ UCS-2 เช่น จำกัด ตัวละครในระนาบหลายภาษาพื้นฐาน (BMP) เมื่อเซิร์ฟเวอร์คอนโซล Win32 (conhost.exe ทุกวันนี้) ได้รับการออกแบบในปี 1990 Unicode เป็นมาตรฐาน 16 บิตดังนั้นบัฟเฟอร์หน้าจอคอนโซลใช้ WCHAR 16 บิตต่อเซลล์อักขระหนึ่งตัว คู่ตัวแทน UTF-16 พิมพ์ออกมาเป็นอักขระกล่องสองตัว
Eryk Sun

3
@ user200783 ไม่สนับสนุนฟอร์มที่สลายตัว โดยปกติหนึ่งสามารถเปลี่ยนเป็นเทียบเท่า NFC นอกจากนี้คอนโซลในโลแคลตะวันตกไม่อนุญาตให้ผสมร่ายมนตร์แบบเต็มความกว้างและครึ่งความกว้าง นอกจากนี้เมื่อใช้ codepage 65001 (UTF-8) ก่อนหน้า Windows 8 จะWriteFileรายงานจำนวนตัวอักษรที่เขียนแทนจำนวนไบต์ดังนั้นผู้เขียนบัฟเฟอร์จะลองไบต์ 'ที่เหลือ' อีกครั้งตามสัดส่วนของจำนวนอักขระที่ไม่ใช่ ASCII . นอกจากนี้ใน 65001 อ่านอักขระที่ไม่ใช่ ASCII ล้มเหลวในการ conhost.exe เพราะถือว่า 1 ไบต์ ANSI ต่อ UTF-16 WideCharToMultiByteรหัสเมื่อโทร
Eryk Sun

2
โปรแกรมสาธิตอย่างง่ายในคำตอบนี้สมมติว่าGetStdHandle(STD_OUTPUT_HANDLE)และ C stdoutเป็นตัวควบคุมคอนโซล ในทางปฏิบัติหากต้องการทดสอบคอนโซลให้ตรวจสอบว่าGetConsoleModeทำได้สำเร็จหรือไม่ นอกจากนี้อย่าใช้_isattyฟังก์ชันC runtime เพื่อตรวจสอบว่า descriptor ไฟล์ I / O ต่ำเป็นคอนโซลหรือไม่ เพียงตรวจสอบอุปกรณ์โหมดตัวละครซึ่งรวมถึงอุปกรณ์NULอื่น ๆ ด้วย โทร_get_osfhandleและตรวจสอบที่จับแทนโดยตรง
Eryk Sun

29

ชนิด

chcp

เพื่อดูหน้ารหัสปัจจุบันของคุณ (ดังที่ Dewfy พูดไว้แล้ว)

ใช้

nlsinfo

เพื่อดูหน้ารหัสที่ติดตั้งทั้งหมดและค้นหาความหมายหมายเลขหน้ารหัสของคุณ

คุณจำเป็นต้องมี Windows Server 2003 ติดตั้งชุดทรัพยากร (ทำงานบน Windows XP) nlsinfoกับการใช้งาน


19
ที่น่าสนใจnlsinfoไม่ปรากฏอยู่บน Windows 7 ของฉัน
โจอี้

2
nlsinfoยังไม่มีอยู่ในเครื่อง Windows XP SP3 ของฉัน
Thomas Owens

2
โอ้ฉันขอโทษ. ฉันคิดว่ามันมาพร้อมกับเครื่องมือ Windows Server Resource Kit ฉันเคยใช้มาแล้วสองสามครั้งในเครื่อง Windows XP SP3 ของฉันก่อนหน้านี้และไม่รู้ว่าไม่ได้ติดตั้งตามค่าเริ่มต้น
Cagdas Altinkaya

อานั่นอธิบายว่าทำไมมันถึงมีอยู่ในเครื่อง Vista ของฉันที่ฉันติดตั้งสิ่งเหล่านั้น
Joey

4
nlsinfoยังไม่มีอยู่ในเครื่อง Windows 10E
Yousha Aleayoub

21

เพื่อตอบคำถามที่สองของคุณอีกครั้ง วิธีการเข้ารหัสงานโจ Spolsky เขียนที่ดีบทความแนะนำเกี่ยวกับเรื่องนี้ แนะนำอย่างยิ่ง


13
ฉันอ่านแล้วและฉันรู้ อย่างไรก็ตามบน Windows ฉันมักจะรู้สึกหลงทางเพราะระบบปฏิบัติการและแอพพลิเคชั่นส่วนใหญ่ดูเหมือนไม่รู้การเข้ารหัสทั้งหมด
danglund

5

คำสั่ง CHCP แสดงเพจรหัสปัจจุบัน มันมีสามหลัก: 8xx และแตกต่างจาก Windows 12xx ดังนั้นการพิมพ์ข้อความภาษาอังกฤษอย่างเดียวคุณจะไม่เห็นความแตกต่างใด ๆ แต่โค้ดเพจแบบขยาย (เช่น Cyrillic) จะถูกพิมพ์ผิด


5
CHCP ไม่แสดงเฉพาะตัวเลข 3 หลักเท่านั้นและไม่อยู่ในรูปแบบ 8 ## 437 เป็นตัวอย่างการเข้ารหัสของสหรัฐอเมริกาและเป็นมาตรฐาน defacto ในระบบภาษาอังกฤษ - 65001 เป็นการเข้ารหัส Unicode (ถ้าฉันจำได้ถูกต้องมันคือ UTF-8 และ 65000 เป็น UTF-7) และสามารถเลือกได้ นอกจากนี้ CMD ยังอนุญาตให้เปลี่ยนเป็นหน้ารหัส 1250 ได้เช่นกัน แต่ฉันไม่รู้ตั้งแต่เมื่อเลือกหน้ารหัสเหล่านี้ (อยู่ภายใต้ Win7)
อดัม LS

4

ฉันผิดหวังกับปัญหาหน้ารหัส Windows มาเป็นเวลานานและปัญหาเรื่องความสามารถในการพกพาของโปรแกรม C และปัญหาการแปลเป็นภาษาท้องถิ่น โพสต์ก่อนหน้ามีรายละเอียดปัญหายาวดังนั้นฉันจะไม่เพิ่มอะไรในส่วนนี้

เพื่อทำให้เรื่องราวสั้น ๆ ในที่สุดฉันก็จบลงด้วยการเขียนเลเยอร์ไลบรารีที่เข้ากันได้ของ UTF-8 ของฉันเองบนไลบรารี C Visual มาตรฐาน C ++ โดยพื้นฐานแล้วไลบรารี่นี้รับรองว่าโปรแกรม C มาตรฐานทำงานได้ถูกต้องในหน้ารหัสใด ๆ โดยใช้ UTF-8 ภายใน

ห้องสมุดนี้เรียกว่า MsvcLibX, สามารถใช้ได้เป็นโอเพนซอร์สที่https://github.com/JFLarvoire/SysToolsLib คุณสมบัติหลัก:

  • ซอร์ส C ถูกเข้ารหัสใน UTF-8 โดยใช้อักขระ char [] สตริง C และ API ไลบรารี C มาตรฐาน
  • ในหน้ารหัสใด ๆ ทุกอย่างจะถูกประมวลผลภายในเป็น UTF-8 ในโค้ดของคุณรวมถึงรูทีน main () argv [] ด้วยอินพุตและเอาต์พุตมาตรฐานแปลงเป็นหน้ารหัสด้านขวาโดยอัตโนมัติ
  • ฟังก์ชันไฟล์ stdio.h ทั้งหมดสนับสนุนชื่อพา ธ UTF-8> 260 ตัวอักษรสูงสุด 64 KBytes
  • แหล่งเดียวกันสามารถคอมไพล์และลิงค์สำเร็จใน Windows โดยใช้ Visual C ++ และ MsvcLibX และ Visual C ++ C ไลบรารี่และใน Linux โดยใช้ gcc และ Linux ไลบรารี่มาตรฐาน C โดยไม่จำเป็นต้องบล็อก #ifdef ... #endif
  • เพิ่มรวมไฟล์ทั่วไปใน Linux แต่หายไปใน Visual C ++ เช่น unistd.h
  • เพิ่มฟังก์ชั่นที่ขาดหายไปเช่นเดียวกับไดเรกทอรี I / O การจัดการลิงค์สัญลักษณ์ ฯลฯ ทั้งหมดนี้รองรับ UTF-8 แน่นอน :-)

รายละเอียดเพิ่มเติมในMsvcLibX README บน GitHubรวมถึงวิธีสร้างไลบรารีและใช้ในโปรแกรมของคุณเอง

ส่วนที่วางจำหน่ายในพื้นที่เก็บข้อมูล GitHub ด้านบนมีหลายโปรแกรมที่ใช้ไลบรารี MsvcLibX นี้ซึ่งจะแสดงความสามารถ เช่นลองใช้เครื่องมือ which.exe ที่มีไดเรกทอรีซึ่งไม่มีชื่อ ASCII ใน PATH ค้นหาโปรแกรมที่ไม่มีชื่อ ASCII และเปลี่ยนหน้ารหัส

อีกเครื่องมือที่มีประโยชน์คือโปรแกรม conv.exe โปรแกรมนี้สามารถแปลงกระแสข้อมูลจากหน้ารหัสใด ๆ เพื่ออื่น ๆ ค่าดีฟอลต์คืออินพุตในหน้ารหัส Windows และเอาต์พุตในหน้ารหัสคอนโซลปัจจุบัน สิ่งนี้ช่วยให้สามารถดูข้อมูลที่สร้างโดยแอพ Windows GUI (เช่น Notepad) ในคอนโซลคำสั่งได้อย่างถูกต้องด้วยคำสั่งง่ายๆเช่น:type WINFILE.txt | conv

ไลบรารี MsvcLibX นี้ไม่ได้เสร็จสมบูรณ์และมีส่วนร่วมในการปรับปรุงให้ดียิ่งขึ้น!


2

ใน Java ฉันใช้การเข้ารหัส "IBM850" เพื่อเขียนไฟล์ ที่แก้ไขปัญหา

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.