关于这个问题已经有一些问题了.我认为我的问题有点不同,因为我没有实际问题,我只是在考虑学术兴趣.我知道Windows的UTF-16实现有时与Unicode标准(例如整理)相矛盾,或者更接近旧UCS-2而不是UTF-16,但我会在这里保留"UTF-16"术语,原因是简单.
背景:在Windows中,一切都是UTF-16.无论你是在处理内核,图形子系统,文件系统还是其他什么,你都要传递UTF-16字符串.Unix意义上没有语言环境或字符集.为了与中世纪版本的Windows兼容,有一个名为"codepages"的东西已经过时但仍然受到支持.AFAIK,只有一个正确且非过时的函数可以将字符串写入控制台,即WriteConsoleW采用UTF-16字符串.此外,类似的讨论也适用于输入流,我也会忽略它.
但是,我认为这代表了Windows API中的一个设计缺陷:有一个通用函数可以用来写入所有被调用的流对象(文件,管道,控制台......)WriteFile,但是这个函数是面向字节的,不是接受UTF-16字符串.文档建议使用WriteConsoleW控制台输出,这是面向文本的,和WriteFile对于其他一切,这是面向字节的.由于控制台流和文件对象都由内核对象句柄表示,并且控制台流可以重定向,因此必须为标准输出流的每次写入调用一个函数,以检查句柄是表示控制台流还是文件,从而破坏多态性.OTOH,我认为Windows在文本字符串和原始字节之间的分离(在许多其他系统中镜像,如Java或Python)在概念上优于Unix的char*方法,忽略编码并且不区分字符串和字节数组.
所以我的问题是:在这种情况下该怎么办?为什么即使在微软自己的库中也没有解决这个问题?.NET Framework和C和C++库似乎都遵循过时的代码页模型.您将如何设计Windows API或应用程序框架来规避此问题?
我认为一般问题(不容易解决)是所有库都假设所有流都是面向字节的,并在此基础上实现面向文本的流.但是,我们看到Windows在操作系统级别上确实有特殊的面向文本的流,并且库无法处理这个问题.因此,无论如何,我们必须对所有标准库进行重大更改.一种快速而肮脏的方法是将控制台视为一种特殊的面向字节的流,只接受一种编码.这仍然要求必须绕过C和C++标准库,因为它们没有实现WriteFile/ WriteConsoleWswitch.那是对的吗?
我按照本教程设置了uwsgi:https://uwsgi.readthedocs.org/en/latest/tutorials/Django_and_nginx.html .我pip install uwsgi在virtualenv中运行,但问题如下:
Command /home/timyitong/superleagues/bin/python -c "import setuptools;__file__='/home/timyitong/superleagues/build/uwsgi/setup.py';exec(compile(open(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-Z9h8Jn-record/install-record.txt --single-version-externally-managed --install-headers /home/timyitong/superleagues/include/site/python2.6 failed with error code 1 in /home/timyitong/superleagues/build/uwsgi
Traceback (most recent call last):
File "/home/timyitong/superleagues/bin/pip", line 9, in <module>
load_entry_point('pip==1.4', 'console_scripts', 'pip')()
File "/home/timyitong/superleagues/lib/python2.6/site-packages/pip/__init__.py", line 148, in main
return command.main(args[1:], options)
File "/home/timyitong/superleagues/lib/python2.6/site-packages/pip/basecommand.py", line 169, in main
text = '\n'.join(complete_log)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 54: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)
这似乎是一个解码问题,但如何解决?我的系统环境是:
Ubuntu 10.04
Django==1.5.1
South==0.8.1 …Run Code Online (Sandbox Code Playgroud) 我一直想知道是否可以在控制台窗口中显示UTF8或UTF16中文文本,例如Console.WriteLine(中文).目前,它显示为???.是否可以启动支持中文字符的控制台会话?
我有一个宽字符文件(希伯来文本)在记事本中看起来很好(以"UTF-8编码"保存),在Notepad ++中读得很好,当我复制并粘贴到MS Word时它看起来也很好.但是当我打开一个"DOS框"(Windows控制台)并转到:"输入file.txt"时,它会打印出乱码.
是的,我在Windows控制台上完成了对Unicode的所有建议:我使用"cmd/u"打开控制台,我将字体更改为Lucida,然后输入:"chcp 65001".
运行Windows 7的PC和运行Windows XP SP3的另一台PC上的问题完全相同.
我正在阅读一个完整的瑞典字符(如äåö)的文件(逐行),但我如何阅读和保存带有瑞典字符的字符串.这是我的代码,我正在使用UTF8编码:
TextReader tr = new StreamReader(@"c:\testfile.txt", System.Text.Encoding.UTF8, true);
tr.ReadLine() //returns a string but Swedish characters are not appearing correctly...
Run Code Online (Sandbox Code Playgroud) 我chcp 65001在Windows shell中遇到命令问题.
我需要生成文件夹中的文件列表.所以我运行cmd.exe,输入
cd folder
dir /B /O:N > list_of_files.txt
Run Code Online (Sandbox Code Playgroud)
它工作,但我遇到了一些特殊的非ASCII字符的问题,这些字符在某些文件名中.所以我补充道
chcp 65001
一切正常,但当我将这些命令放入.bat文件时,脚本不起作用.
所以
cd folder
chcp 65001
dir /B /O:N > list_of_files.txt
Run Code Online (Sandbox Code Playgroud)
不生成列表.
和
cd folder
chcp 65001 && dir /B /O:N > list_of_files.txt
Run Code Online (Sandbox Code Playgroud)
以及
cd folder
chcp 65001 > nul && dir /B /O:N > list_of_files.txt
Run Code Online (Sandbox Code Playgroud)
生成列表,但使用默认编码:/.
一切都在cmd.exe中工作,但不在.bat文件中.
我已经阅读了主题:stackoverflow.com/questions/2182568/batch-script-is-not-executed-if-chcp-was-called,但它没有帮助.
编辑:我部分解决了我的问题,改为chcp 65001,chcp 1250因为所有字符都在这个编码.但实际上这并没有回答这个问题.
我想写一个非ascii字符,让我们说?标准输出.棘手的部分似乎是我想要连接到该字符串的一些数据是从json读取的.考虑以下简单的json文档:
{"foo":"bar"}
Run Code Online (Sandbox Code Playgroud)
我包括这个因为如果我只是想打印?那么它似乎足以简单地写:
print("?")
Run Code Online (Sandbox Code Playgroud)
它将在python2和python3中做正确的事情.
所以我想打印foo与非ascii字符一起的值?.我发现这样做的唯一方法就是它在python2和python3中都有效:
getattr(sys.stdout, 'buffer', sys.stdout).write(data["foo"].encode("utf8")+u"?".encode("utf8"))
Run Code Online (Sandbox Code Playgroud)
要么
getattr(sys.stdout, 'buffer', sys.stdout).write((data["foo"]+u"?").encode("utf8"))
Run Code Online (Sandbox Code Playgroud)
重要的是不要错过u前面的?因为否则UnicodeDecodeError将被python2抛出.
使用这样的print功能:
print((data["foo"]+u"?").encode("utf8"), file=(getattr(sys.stdout, 'buffer', sys.stdout)))
Run Code Online (Sandbox Code Playgroud)
似乎没有用,因为python3会抱怨TypeError: 'str' does not support the buffer interface.
我找到了最好的方法还是有更好的选择?我可以使打印功能起作用吗?
当我尝试使用pip在我的新笔记本(Win 7 64)上安装beautifulsoup4时,我收到此错误:
Cleaning up...
Exception:
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\pip\basecommand.py", line 122, in main
status = self.run(options, args)
File "C:\Python27\lib\site-packages\pip\commands\install.py", line 278, in run
requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundl
e=self.bundle)
File "C:\Python27\lib\site-packages\pip\req.py", line 1234, in prepare_files
req_to_install.assert_source_matches_version()
File "C:\Python27\lib\site-packages\pip\req.py", line 464, in assert_source_ma
tches_version
% (display_path(self.source_dir), version, self))
UnicodeDecodeError: 'ascii' codec can't decode byte 0x9e in position 58: ordinal
not in range(128)
Traceback (most recent call last):
File "C:\Python27\lib\runpy.py", line 162, in _run_module_as_main
"__main__", fname, loader, pkg_name)
File "C:\Python27\lib\runpy.py", …Run Code Online (Sandbox Code Playgroud) 以下代码显示了我的计算机上的意外行为(在Windows XP和Windows 7上的VS 2012上使用Visual C++ 2008 SP1进行了测试):
#include <iostream>
#include "Windows.h"
int main() {
SetConsoleOutputCP( CP_UTF8 );
std::cout << "\xc3\xbc";
int fail = std::cout.fail() ? '1': '0';
fputc( fail, stdout );
fputs( "\xc3\xbc", stdout );
}
Run Code Online (Sandbox Code Playgroud)
我简单编译了cl /EHsc test.cpp.
Windows XP:控制台窗口中的输出
ü0ü(转换为代码页1252,最初显示默认代码页中的一些线条图,可能是437).当我更改控制台窗口的设置以使用"Lucida Console"字符集并再次运行我的test.exe时,输出更改为1ü,这意味着
ü可以使用fputsUTF-8编码来编写字符C3 BCstd::cout 因任何原因都不起作用failbit尝试写字符后,流设置Windows 7:使用Consolas输出??0ü.更有趣.可能写入正确的字节(至少在将输出重定向到文件时)并且流状态正常,但这两个字节被写为单独的字符).
我试图在"Microsoft Connect"(见这里)上提出这个问题,但是MS并没有太大的帮助.你可以在这里看一下 以前曾经问过类似的东西.
你能重现这个问题吗?
我究竟做错了什么?不应该std::cout和fputs有相同的效果?
解决:(排序)继mike.dld的想法,我实现了一个std::stringbuf …
我有一个C#控制台应用程序,我试图在其中做一些ASCII艺术.但是,我想要使用的一些字符是Unicode.所以,我正在搜索互联网/ SO,并找不到关于如何在C#控制台应用程序中将控制台设置为Unicode的综合答案.
TDLR:如何将C#控制台应用程序中的控制台设置为Unicode?
编辑:我在搜索与此问题无关的内容后确实找到了这篇文章.