`
daojin
  • 浏览: 690126 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

wprintf 和 wcout

阅读更多

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;
}

分享到:
评论

相关推荐

    Ansi、Unicode、UTF8字符串之间的转换,wprintf

    使用 wprintf 函数可以输出 Unicode 字符串,并且可以指定输出的宽度和精度。 总结 字符串编码转换是计算机编程中一个非常重要的概念。 Ansi、Unicode 和 UTF8 是三种常见的字符串编码方式,每种编码方式都有其优...

    掌握C语言中的宽字符输入输出:深入`wprintf`、`wscanf`、`fwprintf`、`fwscanf`

    wprintf、wscanf、fwprintf和fwscanf是C标准库中的四个函数,它们用于处理宽字符的输入和输出。本文将详细介绍这些函数的使用方法,并提供实际的代码示例。 wprintf、wscanf、fwprintf和fwscanf是C语言中处理宽字符...

    解析wprintf 中使用%I64d格式化输出LONGLONG的详细介绍

    在C/C++编程中,有时候我们需要处理非常大的整数,这时`LONGLONG`类型就显得尤为重要...在处理`LONGLONG`和`ULONGLONG`这类大整数时,记住使用`%I64d`和`%I64u`格式符,可以确保在Windows环境中正确地进行格式化输出。

    摄氏度,摄氏度符号 ℃怎么打,C,C++源码.zip

    而在C语言中,没有内置的宽字符支持,但可以使用`wchar_t`类型和`wprintf`函数。你需要使用`&lt;wchar.h&gt;`和`&lt;locale.h&gt;`头文件,并设置适当的locale: ```c #include #include #include int main() { setlocale...

    摄氏度,摄氏度符号 ℃怎么打,C,C++源码.rar

    如果你的系统支持宽字符,可以使用`wprintf`和`L'℃'`: ```c #include int main() { wprintf(L"%lc\n", L'\u2103'); return 0; } ``` 4. **自定义转换函数**: 也可以创建一个函数,将Unicode码点转换...

    VC++获取系统当前时间

    std::wcout 当前日期和时间: " (L"%Y-%m-%d %H:%M:%S") ; return 0; } ``` 两种方法各有优缺点。使用`SYSTEMTIME`结构更接近底层,灵活性较高,但需要自己处理格式化和输出。而`CTime`类则提供了更友好的面向...

    字符集编码和理解材料

    首先,"浅谈C中的wprintf和宽字符显示2008.doc"这篇文章可能探讨了C语言中的宽字符处理,特别是`wprintf`函数。`wprintf`是C语言标准库中的一个函数,用于格式化并打印宽字符字符串,它是`printf`函数的宽字符版本。...

    xml.rar_XML VC_msxml_vc xml _xml

    MSXML提供了多种版本,包括MSXML3、MSXML4、MSXML5和MSXML6,每个版本都有其特性和改进。在VC项目中,我们通常会选择适合的MSXML版本进行集成。 要开始在VC项目中使用MSXML,你需要在你的工程中包含相应的头文件和...

    VB API实现简单的程序窗口.rar

    VB 基于API技术实现简单的程序窗口,源码文件说明:用VB的模块模仿写的几个小例子(不用窗体)[源码] ...主要是用到了wsprintf函数,对应于Win32API函数wprintf(Win32API函数wprintf在VB中不能去调用它,调用会出错。)

    VC动态读取access文件内容

    ADO提供了一种简单的方法来访问和操作各种数据源,包括Access数据库。要使用ADO,确保在项目设置中包含`msado15.dll`库,并在代码中包含相关的头文件: ```cpp #include #include #include #pragma comment(lib,...

    MFC获取硬盘序列号

    总的来说,通过MFC获取硬盘序列号涉及到了对Windows底层API的深入理解和应用,对于熟悉C++和MFC的开发者来说,这是一个挑战但也是提升技能的好机会。在实际开发中,应确保正确处理各种可能的异常情况,以提高程序的...

    qt 通过hid获取指定usb设备 并读取数据

    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...

    windows 文本输出

    2. `printf` 和 `wprintf` 函数:C标准库中的这两个函数在控制台上进行格式化输出,适用于ASCII和宽字符字符串。`printf`处理ANSI字符串,`wprintf`处理Unicode字符串。 二、GUI窗口输出 1. `CreateWindowEx` 和 `...

    在c程序中处理汉字

    在C程序中处理汉字是一项涉及编码、存储和输出的关键技能,尤其对于中文用户界面或文本处理的应用至关重要。本文将深入探讨在C程序中处理汉字的方法、挑战及解决方案,旨在为开发者提供全面的理解和实践指导。 ### ...

    vc读取xml内容

    本文将详细讲解如何利用VC++和MSXML组件来读取XML文件的数据。 首先,为了使用MSXML组件,你需要在项目中包含相应的头文件,通常是`msxml2.h`。然后,链接对应的库,如`msxml2.lib`或`msxml6.lib`,具体版本取决于...

    VC++获取WinNT-Win2k当前用户名和密码.zip

    VC++(Microsoft Visual C++)作为一款强大的C++集成开发环境,提供了丰富的API和库函数来实现这一功能。本文将深入探讨如何使用VC++在WinNT和Win2000环境下获取当前用户的用户名和密码。 首先,我们要明确的是,...

    四种方法实现VC枚举系统当前进程

    wprintf(L"Process Name: %wZ\n", &currentProc-&gt;ImageName); currentProc = (PSYSTEM_PROCESS_INFORMATION)((PUCHAR)currentProc + currentProc-&gt;NextEntryDelta); } free(procInfo); } ``` 这种方法提供了更...

    一份解析windows快捷方式文件格式的代码

    此块以`IidILinkInfo`接口标识,接着是接口的版本号和数据。 3. **链接目标ID列表**(LTID):这是一个可选部分,存储了目标文件的网络路径信息,特别是当目标位于网络共享上时。 4. **相对路径信息**:如果快捷...

Global site tag (gtag.js) - Google Analytics