浅墨浓香

想要天亮进城,就得天黑赶路。

导航

第2章 多字节字符与宽字符

Posted on 2015-06-10 09:09  浅墨浓香  阅读(938)  评论(0编辑  收藏  举报
2.1 多字节字符集——每个字符的编码宽度不一,可为一个字节或多个字节。
 (1)ASCII字符只占一个字节
 (2)对于中文、日文等用两个字节
 (3)一个字符串中,如何区分哪个是中文字符,那个是ASCII字符呢?
 “Windows程序设计”16进制(10进制)的编码

W

i

n

d

o

w

s

 

57

69

6E

64

6F

77

73

B3 CC

D0 F2

C9 E8

BC C6

0

87

105

110

100

111

119

115

-77 -52

-48 -14

-55 -24

-68 -58

0

 

  ①说明:ASCII码为一个字节,中文为两个字节,均为负数
  ②优点:节约内存。 
  ③缺点:每次查找,都需要从头到尾扫描,效率低。

    char c[] ="Windows程序设计";
    printf("%d\n",sizeof(c));  //输出16,数组总长度为16字节,含\0
    printf("%d\n",strlen(c));  //输出15,字符的长度为15个字节,不含\0

2.2 宽字节字符集——每个字符的编码宽度都相等,均是两个字节

(1)ASCII字符的处理。扩充为两个字节,在原先的字节前补充一个字节0x00
(2)结束符为两个\0
(3)字符串的解释都是两个字符为单位进行的。所以查找效率快,但内存占用大。

 “Windows程序设计”16进制的编码:

W

i

n

d

o

w

s

 

0057

0069

006E

0064

006F

0077

0073

7A0B

5E8F

8BBE

8BA1

0000

        wchar_t c[] = L"Windows程序设计";
        printf("%d\n",sizeof(c));  //输出24,数组总长度为16字节,含结束符
        printf("%d\n",wcslen(c));  //输出11,字符的长度为11个,不含结束符

2.3兼容两种的字符集——如何兼容呢?

#ifdef _UNICODE
        #define _tcslen wcslen
        #define TCHAR wchar_t
        #define LPTSTR wchar_t*
        #define _T(x) L##x
#else
        #define _tcslen strlen
        #define TCHAR  char
        #define LPTSTR  char*
        #define _T(x)  x
#endif

 【例】TCHAR c[] = _T("Windows程序设计");

    //多字节字符集下
    printf("%d\n",sizeof(c));  //16
    printf("%d\n",_tcslen(c)); //15

    //宽字符集下
    printf("%d\n",sizeof(c));  //24
    printf("%d\n",_tcslen(c)); //11

2.4 字符集的对比

 

ASCII

Unicode

通用版本

字符类型

char\CHAR

wchar_t\WCHAR

TCHAR

函数两种版本

printf
strlen
MessageBoxA

wprintf
wcslen
MessageBoxW

_tprintf 
_tcslen
MessageBox宏:TEXT\_TEXT
     _T\__T

 【例】

#include <stdio.h>
#include <locale.h>
#include <tchar.h>

int main()

{
    //ASCII字符集
    //char c = 'A'; //char为一个字节
     //char str[] = "中国";  //在未出现Unicode前的用法,在求字符串长度时会出问题。
     //printf("%c\n", c);
     //printf("%s\n", str);
     //printf("长度:%d\n",strlen(str));//长度为4,对于ASCII来说,一个汉字为2个字节,被看成是两个字符了。

    //Unicode字符集
    //wchar_t c = L'中'; //Unicode,两个字节
    //wchar_t str[] = L"中国";  //Unicode字符串的用法
    //setlocale(LC_ALL,"chs");
    //wprintf(L"%lc\n", c);//wprintf要求第1个参数为L型的,须加个大写的L
    //wprintf(L"%ls\n",str);
    //wprintf(L"%d\n",wcslen(str));//长度为2,Unicode字符。注意与上面ASCII字符集的比较

    //通用的类型与函数
    TCHAR str[] = _T("中国");
     setlocale(LC_ALL,"chs");
     _tprintf(_T("%s\n"),str);
     _tprintf(_T("%d\n"),_tcslen(str));
     return 0;
 }

2.5 Windows中的字符串函数

通用版本

C语言中的ASCII版本

lstrlen

strlen

Lstrcpy

strcpy

Lstrcpyn

strcpyn

lstrcat

strcat

lstrcmp

strcmp

lstrcmpi

strcmpi

(1)windows中使用sprintf

 #include <stdio.h>  
#include
<windows.h> #include<tchar.h> //控制台下用printf int main() { int a= 12; char szBuffer[100]; sprintf_s(szBuffer,100,"Hello %d\n", a); //在内存中格式化字符串 printf(szBuffer); //控制台下用printf puts(szBuffer); //另一种输出方式 return0; }
//ASCII码版
int WINAPI WinMain(HINSTANCEhInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)
 {   
      int a= 12;
      char szBuffer[100];
      sprintf_s(szBuffer,100,"Hello %d\n", a); //在内存中格式化字符串,标准c语言版本
      MessageBoxA(NULL,szBuffer, "Hello ASCII", MB_OK | MB_ICONINFORMATION); //带A
      return0;
 }

//Unicode版

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
 {
      int a= 12;
      wchar_tszBuffer[100];  //WCHAR
      swprintf_s(szBuffer,100, L"Hello %d\n", a); //在内存中格式化字符串,标准c语言版
      MessageBoxW(NULL,szBuffer, L"Hello Unicode", MB_OK | MB_ICONINFORMATION); //带W
      return0;
 }

 //通用版本

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)

{
       int a= 12;
       TCHARszBuffer[100];  //WCHAR
       _stprintf_s(szBuffer,100,TEXT("Hello %d\n"), a); //在内存中格式化字符串,微软版本的在tchar.h中
       MessageBox(NULL,szBuffer, TEXT("Hello TCHAR"), MB_OK | MB_ICONINFORMATION);
       return0;
 }

(2)自定义的格式化消息框

#include <stdio.h>
  #include <Windows.h>
  #include <tchar.h>
  #include <stdarg.h> 
  int my_printf(const char* szFormat, ...)
 {
      int iRet;
      va_list pArgs; //声明一个参数数组
      va_start(pArgs,szFormat);//pArgs,数组初始化为“...”里面的内容
      iRet =vprintf(szFormat, pArgs); //用数组去格式化字符串szFormat
      va_end(pArgs);  //释放pArgs数组
      returniRet;
  } 

int main()
 {
       int x= 100, y = 200, z = 300;
       my_printf("x=%d,y=%d,z=%d\n", x, y, z);
       return0;
 } 

int CDECL MessageBoxPrintf(TCHAR*szCaption,TCHAR* szFormat,...) //C Declaration,表示C语言默认的函数调用方法:所有参数
                                                                                                    //从右到左依次入栈,这些参数由调用者清除,称为手动清栈
 {
       TCHAR szBuffer[1024];
       va_list pArglist;
       va_start(pArglist,szFormat);
       int i= sizeof(szBuffer);
       _vsntprintf_s(szBuffer,1024,sizeof(szBuffer)/sizeof(TCHAR), szFormat, pArglist); //第2个参数缓冲区大小,第3个参数为TCHAR的个数
       va_end(pArglist);
       returnMessageBox(NULL, szBuffer, szCaption, MB_OK | MB_ICONINFORMATION);
 }

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
 {
       int x= 100, y = 200, z = 300;
       MessageBoxPrintf(TEXT("我的标题"), TEXT("Hellox=%d,y=%d,z=%d"),x,y,z);
       return0;
 }