字符串表示与转换

windows 编程中,存在几种字符串表示方式,包括:

1)C-Style 字符串 char* / wchar_t*;

2)C++ STL 字符串 std::string / std::wstring;

3)  ATL/MFC 字符串 CStringA / CStringW;

以上每个版本都有对应的多字节(MBCS)与Unicode(DBCS)表示,其中多字节存在不同编码方案,使用代码页区分。在 windows 系统中,常见代码页有:

1)MS-DOS Latin US, code page 437,使用一个八位字节表示拉丁字符;

2)windows code page 1251 for Cyrillic, 使用一个八位字节表示斯拉夫字符;

3)code page 936/950/932/949 for ideographic,分别表示 简体中文/繁体中文/日语/韩语,使用一个八位字符表示拉丁字符,使用两个八位字符表示象形文字;

针对象形文字,使用 strlen 函数求字符串长度是没有意义的,strlen 函数简单返回字符串中以 ‘\0‘ 结尾前字符个数。

Unicode 使用两个字节表示一个字符,前128位与 ASCII(American Standard Code for Information Interchange) 保持一致。在使用非象形文字时语言时,有一半空间被浪费,故基于 Unicode 字符进行在编码,形成 utf8。这样,针对拉丁语系,斯拉夫语系等仅需要一个字符表示 Unicode 编码,而象形文字使用2,3,4个字节编码,具体见博客  ”字符集及编码“。在 visual c++开发中,utf8 编码可看作一种特殊代码页,使用函数 WideCharToMultiByte(CP_UTF8,...) 可以得到。

如何维护在一个源文件中维护两种编码方案(MBCS & UNICODE)?

winows 系统如下定义:

 1 typedef wchar_t WCHAR;    // wc,   16-bit UNICODE character
 2
 3 #ifdef  UNICODE
 4 // PTCHAR is a pointer to WCHAR
 5 typedef WCHAR TCHAR, *PTCHAR;
 6 #else
 7 // PTCHAR is a pointer to char
 8 typedef char TCHAR, *PTCHAR;
 9 #endif
10
11 #ifdef  _UNICODE
12 #define _tcscpy        wcscpy
13 #define _tcslen         wcslen
14 ...
15 #else
16 #define _tcscpy     strcpy
17 #define _tcslen     strlen
18 ...
19 #endif
20
21 #ifdef  _UNICODE
22 #define __T(x)      L ## x
23 #define __TEXT(quote) L##quote
24 #else
25 #define __T(x)      x
26 #define __TEXT(quote) quote
27 #endif
28
29 // _T(x) __T(x) TEXT(x) _TEXT(x) __TEXT(x) same meaning
30 #define _T(x)       __T(x)
31 #define _TEXT(x)    __T(x)
32 #define TEXT(quote) __TEXT(quote)

根据以上定义,可以在使用一个源文件维护 C-Style 字符串,具体如下:

1 TCHAR *sz = _T("ch中国");
2 int iLen = _tcslen(sz);
3 TCHAR *sz2 = new TCHAR[iLen + 1];
4 _tcscpy(sz2, sz);
5 delete []sz2;

在项目 Properties->Configuration Prooperties->General 下选择 Use Multi-Byte Character Set(or Not Set ),iLen 值为 6,其中每个汉字使用两个字节;当选择 Use Unicode Character Set 时,iLen 值为 4, 表示 sz 有 4 个字符。

C++ STL 字符串 与 ATL/MFC 字符串是对 TCHAR 字符数据进行封装,表示如下:

 1 // c++ string
 2 typedef basic_string<char, char_traits<char>, allocator<char> >
 3     string;
 4 typedef basic_string<wchar_t, char_traits<wchar_t>,
 5     allocator<wchar_t> > wstring;
 6
 7 // atl/mfc string
 8 typedef ATL::CStringT< wchar_t, StrTraitMFC_DLL< wchar_t > > CStringW;
 9 typedef ATL::CStringT< char, StrTraitMFC_DLL< char > > CStringA;
10 typedef ATL::CStringT< TCHAR, StrTraitMFC_DLL< TCHAR > > CString;
11
12 // 由于c++ string 没有提供一个 TCHAR 版本,通过增加如下定义,
13 // 实现多字节与Unicode自动转换
14 #ifdef _UNICODE
15 #define tstring std::wstring
16 #else
17 #define tstring std::string
18 #endif

通过以上定义,使用 tstring(自定义),CString 可以在一个源文件中维护两种类型字符串。windows 也允许使用特定字符集字符串,提供了 MBCS/Unicode 之间转换函数,具体如下:

 1 // char* -> wchar_t*
 2 //char *sz1 = "ch中国";
 3 // 获取 sz1 字符串转换为 Unicode 长度
 4 int iLen = MultiByteToWideChar(CP_ACP, 0, sz1, strlen(sz1), NULL, 0);
 5 wchar_t* sz2 = new wchar_t[iLen + 1];
 6 MultiByteToWideChar(CP_ACP, 0, sz1, strlen(sz1), sz2, iLen);
 7 sz2[iLen] = ‘\0‘;  // 以 ‘\0‘ 结尾字符串
 8
 9 // wchar_t* -> char*
10 wchar_t* sz3 = L"ch中国";
11 // 获取 sz3 字符串转换为 多字节 长度
12 int iLen2 = WideCharToMultiByte(CP_ACP, 0, sz3, wcslen(sz3), NULL, 0, NULL, NULL);
13 char *sz4 = new char[iLen2 + 1];
14 WideCharToMultiByte(CP_ACP, 0, sz3, wcslen(sz3), sz4, iLen2, NULL, NULL);
15 sz4[iLen2] = ‘\0‘; // 可不使用 L 标志,因为单个字符系统可以零补齐
16
17 // CStringA -> CStringW
18 CStringA szA("ch中国");
19 CStringW szW(szA);
20
21 // CStringW -> CStringA
22 CStringW szW2(L"ch中国");
23 CStringA szA2(szW2);
24
25
26 // unicode -> utf8 -> Unicode
27 // vs 默认使用 CP_ACP 翻译多字节,当需要查看 utf8 编码字符串时,可在 watch 窗口添加 ,s8 查看
28 wchar_t *szUtf16 =  L"ch中国";
29 int len = WideCharToMultiByte(CP_UTF8, 0, szUtf16, wcslen(szUtf16), NULL, 0, NULL, NULL);
30 char *szUtf8 = new char[len + 1];
31 WideCharToMultiByte(CP_UTF8, 0, szUtf16, wcslen(szUtf16), szUtf8, len, NULL, NULL);
32 szUtf8[len] = ‘\0‘;
33 int len2 = MultiByteToWideChar(CP_UTF8, 0, szUtf8, strlen(szUtf8), NULL, 0);
34 wchar_t *szUtf16_2 = new wchar_t[len2 + 1];
35 MultiByteToWideChar(CP_UTF8, 0, szUtf8, strlen(szUtf8), szUtf16_2, len2);
36 szUtf16_2[len2] = ‘\0‘;

编程过程中经常使用不同类型字符串,如何在不同类型字符串见转换呢?代码如下:

 1 // TCHAR* <-> CString
 2 TCHAR *sz = _T("ch中国");
 3 CString cstr(sz);
 4 TCHAR* sz2 = cstr.GetBuffer();
 5
 6 // TCHAR* <-> tsring
 7 tstring tstr(sz);
 8 const TCHAR* sz3 = tstr.c_str();  // tstr.data() is also ok
 9
10 // CString <-> tstring
11 CString cstr2;
12 tstring tstr2;
13 tstr2 = cstr.GetBuffer();
14 cstr2 = tstr.c_str();

原文地址:https://www.cnblogs.com/luofeiju/p/12501873.html

时间: 2024-10-16 19:54:12

字符串表示与转换的相关文章

[转]JS中对象与字符串的互相转换

原文地址:http://www.cnblogs.com/luminji/p/3617160.html 在使用 JSON2.JS 文件的 JSON.parse(data) 方法时候,碰到了问题: throw new SyntaxError('JSON.parse'); 查询资料,大概意思如下: JSON.parse方法在遇到不可解析的字符串时,会抛出SyntaxError异常. 即:JSON.parse(text, reviver),This method parses a JSON text t

5.6.3.5 字符串的大小写转换

ECMAScript中涉及到字符串的大小写转换的方法有4 个:toLowerCase().toLocaleLowerCase().toUpperCase()和toLocaleUpperCase().其中,toLowerCase()和toUpperCase()是两个经典的方法,借鉴自java.lang.String中的同名方法.而 toLocaleLowerCase()和toLocaleUpperCase()方法则是针对特定地区的实现.对有些地区来说,针对地区的方法与其通用的方法得到的结果相同,但

数组-05. 字符串字母大小写转换(10)

输入一个以#结束的字符串,本题要求将小写字母全部转换成大写字母,把大写字母全部转换成小写字母,其它字符不变. 输入格式: 输入在一行中给出一个长度不超过40的.以#结束的非空字符串. 输出格式: 在一行中按照要求输出转换后的字符串. 输入样例: Hello World! 123# 输出样例: hELLO wORLD! 123 import java.util.Scanner; public class Main { public static void main(String[] args) {

*数组-05. 字符串字母大小写转换

1 /* 2 * Main.c 3 * E5-数组-05. 字符串字母大小写转换 4 * Created on: 2014年8月20日 5 * Author: Boomkeeper 6 *********部分通过********* 7 */ 8 9 #include <stdio.h> 10 11 int main(void){ 12 13 char str[40]={-1}; 14 15 gets(str); 16 17 int i,index; 18 for(i=0;i<40;i++

【转】c# 字符串大小写混合转换

c# 字符串大小写混合转换 我是个.net萌新,在大学是计算机应用专业 学的比较杂 出来准备走net方向  培训了两个月了 今天被出了一道上机题  题本来是挺简单的  输入一个字符 如果是大写则转换为小写  如果是小写则转换为大写 难点在于后来我们自发的延伸  并且发现网上也没有针对这种情况的解决方案 所以我自己写了一个应对这种方法了类  发上来给大家共享下  比自带的转化方法更无脑一键一点 而且可以针对于大小写混合则字符串 如ASDFasf$%#%^645765127aAFSAasdfasd

Python一些字符串判断和转换

设s是字符串: s.isalnum()      判断所有字符都是数字或者字母 s.isalpha()  判断所有字符都是字母 s.isdigit()  判断所有字符都是数字 s.islower() 判断 所有字符都是小写 s.isupper()  判断所有字符都是大写 s.istitle()  判断所有单词都是首字母大写,像标题 s.isspace()  判断所有字符都是空白字符 s.upper() 所有小写字符转换成大写 s.lower() 所有大写字符转换成小写 s.capitalize(

JSON实用类,用来实现对象和JSON字符串的互相转换

import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.math.BigDecimal; import java.math.BigInteger; import java.util.ArrayList; import java.util.Lis

06-2. 字符串字母大小写转换(10)

输入一个以#结束的字符串,本题要求将小写字母全部转换成大写字母,把大写字母全部转换成小写字母,其它字符不变. 输入格式: 输入在一行中给出一个长度不超过40的.以#结束的非空字符串. 输出格式: 在一行中按照要求输出转换后的字符串. 输入样例: Hello World! 123# 输出样例: hELLO wORLD! 123 1 #include <stdio.h> 2 3 int main() 4 { 5 char s[40]; 6 int i = 0; 7 do { 8 scanf(&qu

php将标准字符串格式时间转换成unix时间戳_strtotime

php 将标准字符串格式时间转换成unix时间戳的函数为:strtotime函数(PHP 4, PHP 5). strtotime函数详细参考: strtotime - 将任何英文文本的日期时间描述解析为 Unix 时间戳. 函数格式说明: int strtotime ( string $time [, int $now ] ) 本函数预期接受一个包含美国英语日期格式的字符串并尝试将其解析为 Unix 时间戳(自 January 1 1970 00:00:00 GMT 起的秒数),其值相对于 n

C语言 字符串和数字转换函数

atof(将字符串转换成浮点型数) 相关函数 atoi,atol,strtod,strtol,strtoul 表头文件 #include <stdlib.h> 定义函数 double atof(const char *nptr); 函数说明 atof()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时('\0')才结束转换,并将结果返回.参数nptr字符串可包含正负号.小数点或E(e)来表示指数部分,如123.456或123e-2.