wprintf 和 wcout
这篇文章应该是[netsin]的成果,我勤快,记下来。
注:wprintf是C的标准库函数,但wcout不是C++的标准成员,C++中的 L"……" 是宽字符,却未必是unicode字符,这与编译器实现相关。
[乾坤一笑]说:为什么 C/C++ 语言把 L"xx" 定义为由实现决定的呢?这显然是为了 C/C++ 的普适性、可移植性。Bjarne 的观点认为,C++ 的方式是允许程序员使用任何字符集作为串的字符类型。另外,unicode 编码已经发展了若干版本了,是否能永久适合下去也不得而知。有关 unicode 的详细论述以及和其它字符集的比较,我推荐你看《无废话xml》。
以下两段代码的执行环境是 windows xp professional 英文版,编译器是 VS2005RTM。
// C
#include <stdio.h>
#include <locale.h>
int main( void )
{
setlocale( LC_ALL, "chs" );
//setlocale( LC_ALL, "Chinese-simplified" );
//setlocale( LC_ALL, "ZHI" );
//setlocale( LC_ALL, ".936" );
wprintf( L"中国" );
return 0;
}
// C++
#include <iostream>
#include <locale>
using namespace std;
int main( void )
{
locale loc( "chs" );
//locale loc( "Chinese-simplified" );
//locale loc( "ZHI" );
//locale loc( ".936" );
wcout.imbue( loc );
std::wcout << L"中国" << endl;
return 0;
}
说明:别混合使用 setlocale 和 std::locale 。
------------------------- 2006-07-05 记 -------------------------
"VC知识库" 编码为:56 43 D6 AA CA B6 BF E2 00 // ANSI编码
L"VC知识库" 在VC++ 中编码为:56 00 43 00 E5 77 C6 8B 93 5E 00 00 // (windows口中的unicode)编码
L"VC知识库" 在GCC(Dev-CPP4990) 中编码为:56 00 43 00 D6 00 AA 00 CA 00 B6 00 BF 00 E2 00 00 00 // 只是将ANSI编码简单的加0
L"VC知识库" 在GCC(Dev-CPP4992) 中编译失败,报 Illegal byte sequence
L"VC知识库" 在 Dev-CPP4992 中解决步骤为:
a. 将文件保存为 utf-8 编码 // utf-8 是unicode的其中一种,但和(windows口中的unicode)不一样
b. 去掉BOM头:用二进制编辑器(比如VC)去掉刚才utf-8文件的前三个字节 // Linux/UNIX并不使用BOM
c. 使用 gcc/g++ 编译运行
经过以上解决步骤,在 dev-cpp4992 中
"VC知识库" 编码为: 56 43 E7 9F A5 E8 AF 86 E5 BA 93 00 // utf-8编码,注意不再是ANSI编码了,因此用 printf/cout 将输出乱码
L"VC知识库" 编码为: 56 00 43 00 E5 77 C6 8B 93 5E 00 00 // (windows口中的unicode)编码
补充:在mingw32中使用wcout和wstring需要加一些宏,比如
#define _GLIBCXX_USE_WCHAR_T 1
#include <iostream>
int main( void )
{
std::wcout << 1 << std::endl;
}
可以编译通过,但无法Link通过,在网上google了一下,stlport说mingw32有问题,mingw32说是M$的c runtime有问题。
------------------------- 2007-01-05 记 -------------------------
一个多字节字符串和宽字符字符串互相转化的事例
#define _CRT_SECURE_NO_WARNINGS // only for vc8
#include <string>
#include <clocale>
#include <cassert>
inline const std::string to_mbcs( const std::string& src )
{
return src;
}
const std::string to_mbcs( const std::wstring& src )
{
char* old_locale = _strdup( setlocale(LC_CTYPE,NULL) ); // 保存原来的locale
setlocale( LC_CTYPE, "chs" ); // 设置当前locale为chs,这在非简体中文平台上不可缺少
size_t count1 = wcstombs( NULL, src.c_str(), 0 ); // 计算新字符串长度
std::string des( count1, ' ' );
size_t count2 = wcstombs( &des[0], src.c_str(), count1 ); // 转化
assert( count1 == count2 );
setlocale( LC_CTYPE, old_locale ); // 恢复到原来的locale
free( old_locale );
return des;
}
inline const std::wstring to_wcs( const std::wstring& src )
{
return src;
}
const std::wstring to_wcs( const std::string& src )
{
char* old_locale = _strdup( setlocale(LC_CTYPE,NULL) ); // 保存原来的locale
setlocale( LC_CTYPE, "chs" ); // 设置当前locale为chs,这在非简体中文平台上不可缺少
size_t count1 = mbstowcs( NULL, src.c_str(), 0 ); // 计算新字符串长度
std::wstring des( count1, L' ' );
size_t count2 = mbstowcs( &des[0], src.c_str(), count1 ); // 转化
assert( count1 == count2 );
setlocale( LC_CTYPE, old_locale ); // 恢复到原来的locale
free( old_locale );
return des;
}
#include <iostream>
int main( void )
{
using namespace std;
cout << to_mbcs("你好1") << endl;
cout << to_mbcs(L"你好2") << endl;
const locale loc( "chs" );
wcout.imbue( loc );
wcout << to_wcs("你好3") << endl;
wcout << to_wcs(L"你好4") << endl;
}
分享到:
相关推荐
使用 wprintf 函数可以输出 Unicode 字符串,并且可以指定输出的宽度和精度。 总结 字符串编码转换是计算机编程中一个非常重要的概念。 Ansi、Unicode 和 UTF8 是三种常见的字符串编码方式,每种编码方式都有其优...
wprintf、wscanf、fwprintf和fwscanf是C标准库中的四个函数,它们用于处理宽字符的输入和输出。本文将详细介绍这些函数的使用方法,并提供实际的代码示例。 wprintf、wscanf、fwprintf和fwscanf是C语言中处理宽字符...
在C/C++编程中,有时候我们需要处理非常大的整数,这时`LONGLONG`类型就显得尤为重要...在处理`LONGLONG`和`ULONGLONG`这类大整数时,记住使用`%I64d`和`%I64u`格式符,可以确保在Windows环境中正确地进行格式化输出。
而在C语言中,没有内置的宽字符支持,但可以使用`wchar_t`类型和`wprintf`函数。你需要使用`<wchar.h>`和`<locale.h>`头文件,并设置适当的locale: ```c #include #include #include int main() { setlocale...
如果你的系统支持宽字符,可以使用`wprintf`和`L'℃'`: ```c #include int main() { wprintf(L"%lc\n", L'\u2103'); return 0; } ``` 4. **自定义转换函数**: 也可以创建一个函数,将Unicode码点转换...
std::wcout 当前日期和时间: " (L"%Y-%m-%d %H:%M:%S") ; return 0; } ``` 两种方法各有优缺点。使用`SYSTEMTIME`结构更接近底层,灵活性较高,但需要自己处理格式化和输出。而`CTime`类则提供了更友好的面向...
首先,"浅谈C中的wprintf和宽字符显示2008.doc"这篇文章可能探讨了C语言中的宽字符处理,特别是`wprintf`函数。`wprintf`是C语言标准库中的一个函数,用于格式化并打印宽字符字符串,它是`printf`函数的宽字符版本。...
MSXML提供了多种版本,包括MSXML3、MSXML4、MSXML5和MSXML6,每个版本都有其特性和改进。在VC项目中,我们通常会选择适合的MSXML版本进行集成。 要开始在VC项目中使用MSXML,你需要在你的工程中包含相应的头文件和...
VB 基于API技术实现简单的程序窗口,源码文件说明:用VB的模块模仿写的几个小例子(不用窗体)[源码] ...主要是用到了wsprintf函数,对应于Win32API函数wprintf(Win32API函数wprintf在VB中不能去调用它,调用会出错。)
ADO提供了一种简单的方法来访问和操作各种数据源,包括Access数据库。要使用ADO,确保在项目设置中包含`msado15.dll`库,并在代码中包含相关的头文件: ```cpp #include #include #include #pragma comment(lib,...
总的来说,通过MFC获取硬盘序列号涉及到了对Windows底层API的深入理解和应用,对于熟悉C++和MFC的开发者来说,这是一个挑战但也是提升技能的好机会。在实际开发中,应确保正确处理各种可能的异常情况,以提高程序的...
wprintf(L"Serial Number String: (%d) %s\n", wstr[0], wstr); // Read Indexed String 1 res = hid_get_indexed_string(handle, 1, wstr, MAX_STR); wprintf(L"Indexed String 1: %s\n", wstr); qDebug("hid...
2. `printf` 和 `wprintf` 函数:C标准库中的这两个函数在控制台上进行格式化输出,适用于ASCII和宽字符字符串。`printf`处理ANSI字符串,`wprintf`处理Unicode字符串。 二、GUI窗口输出 1. `CreateWindowEx` 和 `...
在C程序中处理汉字是一项涉及编码、存储和输出的关键技能,尤其对于中文用户界面或文本处理的应用至关重要。本文将深入探讨在C程序中处理汉字的方法、挑战及解决方案,旨在为开发者提供全面的理解和实践指导。 ### ...
本文将详细讲解如何利用VC++和MSXML组件来读取XML文件的数据。 首先,为了使用MSXML组件,你需要在项目中包含相应的头文件,通常是`msxml2.h`。然后,链接对应的库,如`msxml2.lib`或`msxml6.lib`,具体版本取决于...
VC++(Microsoft Visual C++)作为一款强大的C++集成开发环境,提供了丰富的API和库函数来实现这一功能。本文将深入探讨如何使用VC++在WinNT和Win2000环境下获取当前用户的用户名和密码。 首先,我们要明确的是,...
wprintf(L"Process Name: %wZ\n", ¤tProc->ImageName); currentProc = (PSYSTEM_PROCESS_INFORMATION)((PUCHAR)currentProc + currentProc->NextEntryDelta); } free(procInfo); } ``` 这种方法提供了更...
此块以`IidILinkInfo`接口标识,接着是接口的版本号和数据。 3. **链接目标ID列表**(LTID):这是一个可选部分,存储了目标文件的网络路径信息,特别是当目标位于网络共享上时。 4. **相对路径信息**:如果快捷...