Как сменить кодировку в консоли windows?
Файл должен выводиться в utf-8, а в консоли – 866, в итоге в браузере отображаются ромбы.
После команды chcp 65001 ничего не поменялось.
Поскольку в консоли используется кодовая страница 866, то если в реестре поменять значение REG_SZ-параметра “866” под ключом [HKLMSYSTEMCurrentControlSetControlNlsCodePage] с “C_866.nls” (по умолчанию) на иное, то и кодировка в cmd также должна измениться.
Но у меня в CodePage таких файлов нет. Есть типы REG.SZ по умолчанию и 4 файла с номерами 932 936 949 950
Вариант постоянно изменять в консоли chcp не подходит, но и не работает. Lucida console подключен в консоли. Cygwin64 Terminal и Gitbash не запускает python server
Какие-то ещё есть варианты?
generate.py
# coding: utf-8
from horoscope import generate_prophecies
from datetime import datetime as dt
def generate_page(head, body):
page = f"<html>{head}{body}</html>"
return page
def generate_head(title):
head = f"""<head>
<meta charset='utf-8'>
<title>{title}</title>
</head>
"""
return head
def generate_body(header, paragraphs):
body = f"<h1>{header}</h1>"
for p in paragraphs:
body = body f"<p>{p}</p>"
return f"<body>{body}</body>"
def save_page(title, header, paragraphs, output="index.html"):
fp = open(output, "w")
today = dt.now().date()
page = generate_page(
head=generate_head(title),
body=generate_body(header=header, paragraphs=paragraphs)
)
print(page, file=fp)
fp.close()
#####################
today = dt.now().date()
save_page(
title="Гороскоп на сегодня",
header="Что день " str(today) " готовит",
paragraphs=generate_prophecies(),
)
horoscope.py
# coding: utf-8
from horoscope import generate_prophecies
from datetime import datetime as dt
def generate_page(head, body):
page = f"<html>{head}{body}</html>"
return page
def generate_head(title):
head = f"""<head>
<meta charset='utf-8'>
<title>{title}</title>
</head>
"""
return head
def generate_body(header, paragraphs):
body = f"<h1>{header}</h1>"
for p in paragraphs:
body = body f"<p>{p}</p>"
return f"<body>{body}</body>"
def save_page(title, header, paragraphs, output="index.html"):
fp = open(output, "w")
today = dt.now().date()
page = generate_page(
head=generate_head(title),
body=generate_body(header=header, paragraphs=paragraphs)
)
print(page, file=fp)
fp.close()
#####################
today = dt.now().date()
save_page(
title="Гороскоп на сегодня",
header="Что день " str(today) " готовит",
paragraphs=generate_prophecies(),
)
При запуске кода (python generate_all.py из командной строки или Ctrl B в саблайме) в этой же папке генерируется файл index.html, и, если поднять сервер в этой же директории (python -m http.server) из консоли win, то в браузере ромбы.
Какая кодировка / кодовая страница cmd.через ехе?
Да, это расстраивает-иногда type
и другие программы
печатают тарабарщину, а иногда и нет.
прежде всего, символы Юникода будут отображаться только если
текущий шрифт консоли содержит символы. Так используйте
шрифт TrueType, такой как консоль Lucida, а не растровый шрифт по умолчанию.
но если шрифт консоли не содержит символ, который вы пытаетесь отобразить,
вы увидите вопросительные знаки вместо тарабарщины. Когда ты … тарабарщина,
там происходит больше, чем просто настройки шрифта.
когда программы используют стандартные функции ввода-вывода c-library, такие как printf
, в
выходная кодировка программы должна соответствовать выходной кодировке консоли, или
вы получите абракадабру. chcp
показывает и задает текущую кодовую страницу. Все
вывод с использованием стандартных функций ввода-вывода c-library рассматривается как
кодировка отображается chcp
.
соответствие выходной кодировки программы с консолью кодирование вывода
может быть выполнено двумя различными способами:
программы, использование Win32 API может писать строки UTF-16LE напрямую
к консоли с
WriteConsoleW
.
Это единственный способ получить правильный вывод без установки кодовых страниц. И
даже при использовании этой функции, если строка не находится в кодировке UTF-16LE
для начала программа Win32 должна передать правильную кодовую страницу
MultiByteToWideChar
.
Кроме того,
WriteConsoleW
не будет работать, если вывод программы перенаправляется;
в этом случае требуется больше манипуляций.
type
работает некоторые из время, потому что оно проверяет начало каждого файла для
UTF-16LE Метка Порядка Байтов
(BOM), т. е. байт 0xFF 0xFE
.
Если он найдет такое
отметьте, он отображает символы Unicode в файле, используя WriteConsoleW
независимо от текущей кодовой страницы. Но когда!–9–>ing любой файл без
UTF-16LE BOM или для использования символов, отличных от ASCII, с любой командой
это не зовет WriteConsoleW
– вам нужно будет установить
консольная кодовая страница и кодирование вывода программы для соответствия каждой другой.
как мы можем выяснить это?
вот тестовый файл, содержащий символы в кодировке 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 xyzn"
"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:andrewprojectssx59084>chcp
Active code page: 850
Z:andrewprojectssx59084>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}
, что если мы … –9–> файлы, которые были сохранены? Они содержат точное
те же байты, что были напечатаны на консоли.
Z:andrewprojectssx59084>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:andrewprojectssx59084>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 на
запустите файл и используйте специальные API-интерфейсы Windows для его печати.
мы можем увидеть это, открыв cmd.exe
в отладчике, когда он идет к type
из файла:
после type
открывает файл, он проверяет наличие спецификации 0xFEFF
-т. е. байт
0xFF 0xFE
в прямой и, если есть такая спецификация, type
устанавливает
внутренний fOutputUnicode
флаг. Этот флаг проверяется позже, чтобы решить
звонить ли WriteConsoleW
.
но это единственный способ получить type
для вывода Unicode и только для файлов
которые имеют BOMs и находятся в UTF-16LE. Для всех остальных файлов и программ
у которых нет специального кода для обработки вывода консоли, ваши файлы будут
интерпретируется в соответствии с текущей кодовой страницей и, скорее всего, будет отображаться как
тарабарщина.
вы можете подражать, как type
выводит Unicode на консоль в ваших собственных программах следующим образом:
#include <stdio.h>
#define UNICODE
#include <windows.h>
static LPCSTR lpcsTest =
"ASCII abcde xyzn"
"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:andrewprojectssx59084>chcp 65001
Active code page: 65001
Z:andrewprojectssx59084>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("errorn");
}
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:andrewprojectssx59084>.test
ASCII abcde xyz
German äöü ÄÖÜ ß
Polish ąęźżńł
Russian абвгдеж эюя
CJK 你好
мораль истории?
type
может печатать файлы UTF-16LE со спецификацией независимо от текущей кодовой страницы- программы Win32 можно запрограммировать для вывода Unicode на консоль, используя
WriteConsoleW
. - другие программы, которые устанавливают кодовую страницу и соответствующим образом настраивают свою выходную кодировку, могут печатать Unicode на консоли независимо от того, какая кодовая страница была при запуске программы
- для всего остального вам придется возиться с
chcp
, и, вероятно, все равно будет странно выход.
Кодировки в windows / песочница / хабр
В данной статье пойдёт речь о кодировках в Windows. Все в жизни хоть раз использовали и писали консольные приложения как таковые. Нету разницы для какой причины. Будь-то выбивание процесса или же просто написать «Привет!!! Я не могу сделать кодировку нормальной, поэтому я смотрю эту статью!».
Тем, кто ещё не понимает, о чём проблема, то вот Вам:
А тут было написано:
echo Я абракадабра, написанная автором.
Но никто ничего не понял.
В любом случае в Windows до 10 кодировка BAT и других языков, не использует кодировку поддерживающую Ваш язык, поэтому все русские символы будут писаться неправильно.
1. Настройка консоли в батнике
Сразу для тех, кто пишет chcp 1251 лучше написать это:
assoc .bat = .mp4
Первый способ устранения проблемы, это
Notepad
. Для этого Вам нужно открыть Ваш батник таким способом:
Не бойтесь, у Вас откроется код Вашего батника, а затем Вам нужно будет сделать следующие действия:
Если Вам ничего не помогло, то преобразуйте в UTF-8 без BOM.
2. Написание консольных программ
Нередко люди пишут консольные программы(потому что на некоторых десктопные писать невозможно), а кодировка частая проблема.
Первый способ непосредственно Notepad , но а если нужно сначала одну кодировку, а потом другую?
Сразу для использующих chcp 1251 пишите это:
del C:Program Data
echo Mne pofig
pause
Второй способ это написать десктопную программу, или же использовать Visual Studio. Если же не помогает, то есть первое: изменение кодировки вывода(Пример на C ).
#include <iostream>
#include <windows.h>
int main() {
SetConsoleCP(номер_кодировки);
SetConsoleOutputCP(номер_кодировки);
}
Если же не сработает:
#include <math.h> //Не забываем про библиотеку Math.
char bufRus[256];
char* Rus(const char* text) {
CharToOem(text, bufRus);
return bufRus
}
int main {
cout << "Тут пишите, что угодно!" << endl;
system("pause")
return 0
}
3. Изменение chcp 1251
Если же у Вас батник, то напишите в начало:
chcp 1251 >nul
for /f "delims=" %%A in ("Мой текст") do >nul chcp 866& echo.%%A
Теперь у Нас будет нормальный вывод в консоль. На других языках (С ):
SetConsoleOutputCP(1251)
//А тут добавляете тот цикл, который был в батнике
4. Сделать жизнь мёдом
При использовании данного способа Вы не сможете:
- Разрабатывать приложения на Windows ниже 10
- Спасти мир от данной проблемы
- Думать о других людях
- Разрабатывать десктопные приложения, так как Вам жизнь покажется мёдом
- Сменить Windows на версию ниже 10
- Ну и понимать людей, у которых Windows ниже 10
Установить Windows 10. Там кодировка консоли специально подходит для языка страны, и Вам больше не нужно будет беспокоиться об этой проблеме. Но у Вас появится ещё 6 проблем, и вернуться к предыдущей лицензионной версии Windows Вы не сможете.