Кодировки в Windows / Песочница / Хабр

Как сменить кодировку в консоли 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

spoiler

# 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

spoiler

# 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 – вам нужно будет установить
консольная кодовая страница и кодирование вывода программы для соответствия каждой другой.

:/>  Кракозябры при выводе результатов в файл из cmd | Блог -

как мы можем выяснить это?

вот тестовый файл, содержащий символы в кодировке 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 и BAT-файлов | Белые окошки

мы можем увидеть это, открыв cmd.exe в отладчике, когда он идет к type
из файла:

enter image description here

после 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 10 — возможности и практическое применение

Кодировки в windows / песочница / хабр

В данной статье пойдёт речь о кодировках в Windows. Все в жизни хоть раз использовали и писали консольные приложения как таковые. Нету разницы для какой причины. Будь-то выбивание процесса или же просто написать «Привет!!! Я не могу сделать кодировку нормальной, поэтому я смотрю эту статью!».

Тем, кто ещё не понимает, о чём проблема, то вот Вам:

image

А тут было написано:

echo Я абракадабра, написанная автором.

Но никто ничего не понял.

В любом случае в Windows до 10 кодировка BAT и других языков, не использует кодировку поддерживающую Ваш язык, поэтому все русские символы будут писаться неправильно.

1. Настройка консоли в батнике

Сразу для тех, кто пишет chcp 1251 лучше написать это:

assoc .bat = .mp4

Первый способ устранения проблемы, это

Notepad

. Для этого Вам нужно открыть Ваш батник таким способом:

image

Не бойтесь, у Вас откроется код Вашего батника, а затем Вам нужно будет сделать следующие действия:

image

Если Вам ничего не помогло, то преобразуйте в 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 Вы не сможете.