概述C中的宽字符input/输出总是从正确的(系统默认)编码读取/写入?
我主要感兴趣的是类似Unix的系统(例如,便携式POSIX),因为看起来@R_403_5087@对于宽字符是很奇怪的。
读取和写入宽字符函数(如getwchar()和putwchar() )总是“做正确的事情”,例如从utf-8中读取,并在设置的locale中写入utf-8。手动调用wcrtomb()并使用例如fputs()打印string? 在我的系统(openSUSE 12.3)中, $LANG设置为en_GB.UTF-8他们似乎做了正确的事情(检查输出,我看到了什么看起来像UTF-8,即使string使用wchar_t存储和使用宽字符function)。
但是我不确定这是否有保证。 例如cprogramming.com指出:
[宽字符]不应该用于输出,因为虚假零字节和其他含义相同的低ASCII字符(如\’/\’和\’ n\’)可能会散布在整个数据中。
如何链接Cmake中的curses.h?
便携式的方式把标准输出在二进制模式
Qt:@R_403_5087@函数是无法parsing的外部符号
查找function区button的窗口句柄
WPF MVVMclosures窗口
这似乎表明,输出宽字符(推测使用宽字符输出function)可能会造成严重破坏。
由于C标准似乎没有提到编码,所以我真的不知道在使用wchar_t时应用何种编码方式。 所以我的问题是,如果我的应用程序不需要知道所使用的编码,那么读,写和使用宽字符是一个适当的事情。 我只需要string长度和控制台宽度( wcswIDth() ),所以在处理文本时处处使用wchar_t似乎是理想的。
公共3270服务器
asynchronous完成例程I / O,封装在类中的例程指针
C# – @R_403_5087@窗体,解除面板控制的animation
CMake在linux中构build共享对象.so文件
在Visual Studio 2008中是否有stoll()/ stroll()(string long long)替代方法?
管理宽字符stdio函数的行为及其与语言环境的关系的相关文本来自POSIX XSH 2.5.2流方向和编码规则:
http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.HTML#tag_15_05_02
基本上,宽字符的stdio函数总是在file流变为宽的时候写入有效的编码(根据LC_CTYPE语言环境类别) 这意味着第一次调用广泛的stdio函数,或者使用fwIDe将方向设置为较宽。 所以只要一个合适的LC_CTYPE语言环境实际上匹配所需的“系统”编码(例如UTF-8),当你开始使用流时,一切都应该没问题。
但是,您不应忽视的一个重要考虑因素是您不能在同一个file流上混合使用字节和宽泛 *** 作的 *** 作。 不遵守这一规则不是可报告的错误; 它只是导致未定义的行为 。 因为大量的库代码假设stderr是以字节为导向的(有些甚至对stdout做了相同的假设),所以我强烈建议不要在标准流上使用面向广泛的功能。 如果你这样做,你需要非常小心你使用的库函数。
真的,我想不出任何理由来使用广泛的功能。 fprintf完全能够使用%ls说明符将宽字符字符串发送到面向字节的file流。
只要区域设置正确,在使用UTF-8的系统上使用宽字符功能就不会有任何处理UTF-8文件的问题。 他们将能够正确地解释事物,即他们将把字符视为1-4字节(在输入和输出中)。 你可以用这样的东西来测试它:
#include <stdio.h> #include <locale.h> #include <wchar.h> int main() { setlocale(LC_CTYPE,\”en_GB.UTF-8\”); // setlocale(LC_CTYPE,\”\”); // to use environment variable instead wchar_t *txt = L\”£Δᗩ\”; wprintf(L\”The string %ls has %d charactersn\”,txt,wcslen(txt)); } $ gcc -o loc loc.c && ./loc The string £Δᗩ has 3 characters
如果不小心使用多字节字符串的标准函数(尤其是字符函数),事情就会开始中断,例如:
char *txt = \”£Δᗩ\”; printf(\”The string %s has %zu charactersn\”,strlen(txt)); $ gcc -o nloc nloc.c && ./nloc The string £Δᗩ has 7 characters
字符串在这里仍然正确打印,因为它本质上只是一个字节流,而且由于系统期待UTF-8序列,所以它们被完美地翻译。 当然, strlen报告字符串中的字节数7(加上 ),不理解字符和字节是不相等的。
在这方面,由于ASCII和UTF-8之间的兼容性,只要你小心,你通常可以将UTF-8文件视为简单的多字节C字符串。
还有一定程度的灵活性。 可以将一个标准的C字符串(作为一个多字节字符串)很容易地转换成一个宽字符串:
char *stdtxt = \”ASCII and UTF-8 €£¢\”; wchar_t buf[100]; mbstowcs(buf,stdtxt,20); wprintf(L\”%ls has %zu wIDe charactersn\”,buf,wcslen(buf)); Output: ASCII and UTF-8 €£¢ has 19 wIDe characters
一旦你在一个流上使用宽字符功能,它将被设置为宽屏幕方向。 如果以后要使用标准的字节I / O函数,则需要先重新打开该流。 这可能是为什么建议不要在stdout上使用它。 但是,如果您只在stdin和stdout (包括您链接的任何代码)上使用宽字符功能,则不会有任何问题。
除了ASCII之外,不要使用fputs 。
如果你想写下让我们说的UTF8,然后使用一个函数,返回由utf8字符串使用的实际大小,并使用fwrite写好字节数,而不用担心字符串内的恶意\’ \’。
总结
以上是内存溢出为你收集整理的C中的宽字符input/输出总是从正确的(系统默认)编码读取/写入?全部内容,希望文章能够帮你解决C中的宽字符input/输出总是从正确的(系统默认)编码读取/写入?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
请登录后查看评论内容