1. 程式人生 > >TCHAR資料型別介紹

TCHAR資料型別介紹

  並不是所有的Windows作業系統都支援UNICODE編碼的API(例如早期的Windows98), 這就造成了兩種結果:某些版本的Windows應該應用wchar_t來儲存字元, 某些平臺的Windows應該使用char型別來儲存字元, 顯然這兩種型別的變數是無法混用的。

  為了解決該問題, Windows從一開始設計Windows時, 就提供了一整套方案, 對於支援ASCII字符集的API函式, 函式使用字母A作為字尾;對於支援UNICODE字符集的API函式, 則使用字母W作為字尾。例如:FormatMessage函式就提供了FormatMessageA和FormatMessageW兩個版本。

  文件記載及我們使用的API函式, 實際是定義在Windows.h檔案中的一組“巨集”, 這組巨集在UNICODE環境下將呼叫函式對映為字尾為W的函式;在ASCII環境下將呼叫函式對映為字尾為A的函式。

  tchar.h標頭檔案提供了一個數據型別TCHAR, 這個型別在UNICODE環境下將對映為wchar_t型別;在ASCII環境下對映為char型別。另外, tchar.h還提供了一組C語言字串操作符的替代巨集, 以_t開頭, 例如_tcslen函式, 在UNICODE環境下被對映成為wcslen函式, 在ASCII環境下被對映成為strlen函式。

  最後, tchar.h提供了_T巨集, 該巨集具有一個字串型別引數, 在UNICODE環境下, 該巨集會為字串前面加上L符號。

// 定義巨集UNICODE和_UNICODE, 一旦定義了該巨集, C語言編譯器將在UNICODE環境下工作
// 注意, 一般情況下需要定義UNICODE巨集和_UNICODE巨集, 因為不同版本的C編譯器要求不同

// 在正式工作時, 並不需要定義這兩個巨集, 只需要在"專案屬性->配置屬性->字符集"中選擇
// UNICODE字符集或是多位元組字符集即可, 開發環境會自動定義相應的巨集
#if !defined(UNICODE)
#define UNICODE
#endif

#if !defined(_UNICODE)
#define _UNICODE
#endif

// 在所有標頭檔案之前包含tchar.h標頭檔案
// 這是程式可以應用各類替代巨集的基礎
#include <tchar.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

/**
 * 顯示一個字元, ASCII版本
 * 引數:c, 要顯示的字元變數
 */
void ShowCharacterA(char c)
{
	// 在ASCII版本中, 選用printf函式來顯示字串
	printf("(A)字元 %c 佔據空間 %d", c, sizeof(c));
}

/**
 * 顯示一個字元, UNICODE版本
 * 引數:c, 要顯示的字元變數
 */
void ShowCharacterW(wchar_t wc)
{
	// 在UNICODE版本中, 選用wprintf函式來顯示UNICODE字串
	wprintf(L"(W)字元 %c 佔據空間 %d", wc, sizeof(wc));
}

/**
 * 顯示一個字串, ASCII版本
 * 引數:lpcsz, 要顯示的字元變數
 */
void ShowStringA(const char* lpcsz)
{
	// 在ASCII版本中, 選用printf函式來顯示ASCII字串, 
	// 選用strlen函式來測量字串長度
	printf("/n(A)字串 %s 長度為%d", lpcsz, strlen(lpcsz));
}

/**
 * 顯示一個字串, UNICODE版本
 * 引數:lpcwsz, 要顯示的字元變數
 */
void ShowStringW(const wchar_t* lpcwsz)
{
	// 在UNICODE版本中, 選用wprintf函式來顯示UNICODE字串, 
	// 選用wcslen函式來測量字串長度
	wprintf(L"/n(W)字串 %s 長度為%d", lpcwsz, wcslen(lpcwsz));
}


////////////////////////////////////////////////////

// 下面這一組編譯器指令, 根據是否定義UNICODE(或_UNICODE)巨集, 對映不同的函式
// 可以刪除#if和#endif之間的程式碼, 檢視執行結果的變化, 思考產生這種變化的原因
#if defined(UNICODE) | defined(_UNICODE)

// 定義ShowCharacter巨集對映到ShowCharacterW函式
#define ShowCharacter ShowCharacterW

// 定義ShowString巨集對映到ShowStringW函式
#define ShowString ShowStringW

#else

// 定義ShowCharacter巨集對映到ShowCharacterA函式
#define ShowCharacter ShowCharacterA

// 定義ShowString巨集對映到ShowStringA函式
#define ShowString ShowStringA

#endif

////////////////////////////////////////////////////

// 定義緩衝區長度為512個字元
#define BUF_LEN 512

int _tmain(int argc, TCHAR* argv[])
{
	// 定義變數, 儲存字元
	TCHAR c = _T('A');

	// 定義字元陣列, 儲存字串
	TCHAR szStr[] = _T("ABC大家好");

	// 定義指向字串的指標
	TCHAR* lpszStr = _T("Hello你好");

	// 定義指向字串的常量指標
	const TCHAR* lpcszStr = _T("GoodBye再見");

    int bSame;

	// 定義BUF_LEN長度的字元陣列作為緩衝區
	TCHAR szBuffer[BUF_LEN] = _T("");       

	// 定義ASCII字符集緩衝區
	char szBufferA[BUF_LEN] = "";

	// 定義UNICODE字符集緩衝區
	wchar_t szBufferW[BUF_LEN] = L"";

	// 定義錯誤程式碼22
	const int nError = 22;

	// 設定語言環境為中文
	_tsetlocale(LC_ALL, _T("zhi"));

	// 呼叫ShowCharacter巨集
	ShowCharacter(c);

	// 呼叫ShowCharacter巨集
	ShowString(szStr);
	ShowString(lpszStr);
	ShowString(lpcszStr);

	// _tcsicmp是tchar.h中定義的巨集, 
	// 在不同的字符集環境下對映為stricmp或wcsicmp函式
	bSame = _tcsicmp(lpszStr, lpcszStr);

	if (bSame == 0) 
	{
		// _tprintf是tchar.h中定義的巨集, 在不同字符集環境下對映為printf或wprintf函式
		_tprintf(_T("/n字串 %s 與 %s 相同"), lpszStr, lpcszStr);
	} 
	else 
		_tprintf(_T("/n字串 %s 與 %s 不同"), lpszStr, lpcszStr);

	// _tcscpy_s是tchar.h中定義的巨集,
	// 在不同字符集環境下對映為strcpy_s或wcscpy_s函式(_s表示安全版本函式)
	_tcscpy_s(szBuffer, BUF_LEN, lpszStr);

	// _tcscat_s是tchar.h中定義的巨集, 
	// 在不同字符集環境下對映為strcat_s或wcscat_s函式(_s表示安全版本函式)
	_tcscat_s(szBuffer, BUF_LEN, lpcszStr);

	// _tcslen是tchar.h中定義的巨集, 
	// 在不同字符集環境下對映為strlen或wcslen函式
	_tprintf(_T("/n字串 %s 長度為 %d"), szBuffer, _tcslen(szBuffer));

	// 接下來, 我們看一下FormatMessage函式在不同環境下的應用

	// ASCII環境下應用, 第5個引數使用char型別陣列作為緩衝
	FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, nError, 0, szBufferA, BUF_LEN, NULL);
	printf("/n錯誤資訊:%s", szBufferA);

	// UNICODE環境下應用, 第5個引數使用wchar_t型別陣列作為緩衝
	FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, nError, 0, szBufferW, BUF_LEN, NULL);
	wprintf(L"錯誤資訊:%s", szBufferW);

	// 自適應環境, 第5個引數使用TCHAR型別陣列作為緩衝
	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, nError, 0, szBuffer, BUF_LEN, NULL);
	_tprintf(_T("錯誤資訊:%s"), szBuffer);

	_tprintf(_T("/n"));
	system("pause");
	return 0;
}


相關推薦

TCHAR資料型別介紹

  並不是所有的Windows作業系統都支援UNICODE編碼的API(例如早期的Windows98), 這就造成了兩種結果:某些版本的Windows應該應用wchar_t來儲存字元, 某些平臺的Windows應該使用char型別來儲存字元, 顯然這兩種型別的變數是無法混用

prometheus的資料型別介紹

一、簡介 Prometheus將所有采集到的樣本資料以時間序列(time-series)的方式儲存在記憶體資料庫中,並定時儲存在硬碟上。時間序列中的每一個樣本由以下三部分組成。 指標(metric): metric name和描述當前樣本特徵的labelsets組成,參考格式

6、mysql資料型別介紹

MySQL資料型別,可以被分為3類:數值型別、日期和時間型別以及字串(字元)型別    方括號(“[”和“]”)指出可選的型別修飾符的部分   M       指出最大的顯示尺寸。最大的合

轉 Redis五種資料型別介紹

概述 Redis的鍵值可以使用物種資料型別:字串,散列表,列表,集合,有序集合。本文詳細介紹這五種資料型別的使用方法。本文命令介紹部分只是列舉了基本的命令,至於具體的使用示例,可以參考Redis官方文件:Redis命令大全 字串型別 字串是Redis中最基本的資料型別,

mysql資料庫內STRING系列資料型別介紹

varchar(M):       用於儲存可變長度的字串。  字串佔用空間隨字串實際長度佔用空間變化。   實際長度 <= 設定長度M。   M範圍:1~255。   需要1到2個位元組來儲存一個字元。 char(M):        用於儲存定長的字串。  

day 07 元組,字典和集合等資料型別介紹

元組:就是一個不可變的列表 1.用途,當我們需要記錄多個值,並且沒有更改的需求的時候,應該使用元組 2定義方式:使用,在 ( ) 中分隔開多個任意型別的值 注:t=("egg",),如當列表中只有一個值的時候,在末尾加上 , 逗號 t=tuple("hello")  # 元組和列表的型別的型

MYSQL中資料型別介紹

一、MySQL的資料型別 主要包括以下五大類: 整數型別:BIT、BOOL、TINY INT、SMALL INT、MEDIUM INT、 INT、 BIG INT 浮點數型別:FLOAT、DOUBLE、DECIMAL 字串型別:CHAR、VARCHAR、TIN

redis命令及操作記錄以及redis的五種資料型別介紹

相關啟動命令(linux): redis-server啟動命令 sudo /usr/local/bin/redis-server /home/lbxzfr/config/redis/redis.conf  redis_cli客戶端連結命令 redis-cli -h loca

Redis五種資料型別介紹

概述 Redis的鍵值可以使用物種資料型別:字串,散列表,列表,集合,有序集合。本文詳細介紹這五種資料型別的使用方法。本文命令介紹部分只是列舉了基本的命令,至於具體的使用示例,可以參考Redis官方文件:Redis命令大全 字串型別 字串是Redis中最基本的資料型

PostgreSQL 資料型別介紹(四)

uuid型別 UUIDs could be generated by client applications or other libraries invoked through a server-side function. specifi

Redis常用資料型別介紹、使用場景及其操作命令

Redis目前支援5種資料型別,分別是: String(字串)List(列表)Hash(字典)Set(集合)Sorted Set(有序集合) 下面就分別介紹這五種資料型別及其相應的操作命令。 1. String(字串) String是簡單的 key-value 鍵值

MySQL資料型別介紹

①BLOB和TEXT值也會引起自己的一些問題,特別是執行了大量的刪除或更新操作的時候。刪除這種值會在資料表中留下很大的"空洞",以後填入這些"空洞"的記錄可能長度不同,為了提高效能,建議定期使用 OPTIMIZE TABLE 功能對這類表進行碎片整理.②使用合成的(synthetic)索引。合 成的索引列在

MySQL 中的資料型別介紹

據我統計,MySQL支援39種(按可使用的型別欄位統計,即同義詞也作多個)資料型別。下面的介紹可能在非常古老的MySQL版本中不適用。 1、概述     要了解一個資料庫,我們也必須瞭解其支援的資料型別。     mysql支援所有標準的SQL資料型別,主要分

PostgreSQL 資料型別介紹(五)OID的理解

系統表, 系統表之間基本上都是以oid關聯. 例如pg_attrdef.adrelid 關聯 pg_class.oid 先介紹下oid的使用: 以系統表 pg_class為例,檢視下postgres裡各個物件(表、序列、索引 等)的oid

MySQL全面瓦解3:資料型別介紹與分析

概述 MySQL支援很多資料型別,以便我們能在複雜的業務場景中支援各種各樣的資料格式,儲存適當的資料內容。我們在設計資料庫時,正確的使用資料庫型別對整個資料庫的整潔和高效,會有很大的幫助。 目前常用的資料型別大致上可以分為4大類:整數型別、浮點數型別、字串(字元)型別、日期/時間型別。詳細如下 4大類

JAVA_資料型別介紹與基本資料型別之間的運算規則

## 基本資料型別 * 整型: `byte、short、int、long` `java` 的整型常量預設為`int`型,在`java`程式中變數通常宣告為`int`型,除非不足以表示較大的數才用`long`,而在宣告`long`型常量必須在後面加上`l`或`L`。 | 型別 | 佔用儲存空

第4章:介紹python物件型別/4.1 python的核心資料型別/4.4 字典

建立字典 格式:用大括號括起來,每一對以:隔開 內容:key和value的值隨便,數字、字元、列表、集合、元組混合都可以 注意:如果key相同,會用新的value覆蓋舊的value;這裡的key相同指的是要麼都是數字,要麼都是字元才算相同,比如1和“1”不算相同的

第4章:介紹python物件型別/4.1 python的核心資料型別/4.3 列表

獲取操作 >>> L = [123,'abc',1.23] >>> L[0]  從左邊開始獲取 123 >>> L[-1]   從右邊開始獲取 1.23 >>>

第4章:介紹python物件型別/4.1 python的核心資料型別/4.2 字串/4.2.4 字串格式化、字串編輯HTML或者XML語法、使用正則表示式

字串格式化 %s 方式格式化: >>> "%s,abc,%s" %('123','456') '123,abc,456' {數字}方式格式化: >>> "{0},abc,{1}".format('123','456') '123,a

第4章:介紹python物件型別/4.1 python的核心資料型別/4.2 字串/4.2.3 字串查詢、替換、分解、轉大小寫

字串查詢/替換/分解/轉大小寫 字串查詢 >>> S 'abcd' >>> S.find("bc") 1 替換 >>> S.replace("bc","xyz") 'axyzd' 分解 >>>