2011-10-20 56 views
0

我試圖通過在C++ WinAPI中將每個字母的int值相加在一起來將字符串轉換爲數字。所以在ASCII中; std :: string「AA」將等於130(65 + 65)從std :: string&std :: wstring獲取char整數值

該字符串可以是std :: string或std :: wstring。

爲什麼下面的函數總是返回零的值而不管我輸入什麼字母?它不應該返回字母的ASCII或Unicode整數值嗎?

printf("TEST a: %d \n", _tstoi(_T("a"))); 
printf("TEST A: %d \n", _tstoi(_T("A"))); 
printf("TEST b: %d \n", _tstoi(_T("b"))); 

我的VC++應用目前在Unicode中,&以前的代碼打印出零每個字母。我記得聽說Unicode與ASCII字符串有很大的區別,能清除除了Unicode之外還有什麼不同之處,它有一個類似30,000長的字符庫,而ASCII是256(我認爲?)?

+3

也許感興趣,喬爾的「絕對最低每一個軟件開發人員絕對,積極必須知道的關於Unicode和字符集(沒有藉口!)」 http://www.joelonsoftware.com/articles/Unicode.html – HostileFork

回答

1

* toi系列函數將字符串表示轉換爲整型表示,即「10」變爲10.您真正想要做的是根本不轉換。它更改爲:

 
printf("TEST a: %d \n", _T('a')); 
printf("TEST A: %d \n", _T('A')); 
printf("TEST b: %d \n", _T('b')); 

至於unicode的,底層的表示依賴於編碼(例如UTF-8,這是非常流行的,映射LSB與ASCII表)。

+0

所以可以這樣做來獲得字符串的總和... int x + =(int)_T(「a」); ?或者,也許我應該做長時間投射或無符號整型投射?或者甚至可能是靜態投射? –

+0

所有的char類型都只是無符號整型,除了可能的static_cast之外,沒有任何真正需要的轉換來抑制與位寬差別有關的可能的編譯器警告。 unsigned int x = _T('a');例如應該罰款。 _T(「a」)包含一個NULL終結符,實際上是一個2長度的數組。 – Ylisar

3

MSDN文章說:

「的輸入字符串爲可以被解釋 作爲指定類型的數值字符序列的功能停止在第一字符讀取 輸入字符串。它不能識別爲 的一部分。「

如果測試包含實際數字unicode字符串的代碼,你會看到正確的輸出:

printf("TEST 1: %d \n", _tstoi(_T("1"))); 

輸出:

TEST 1: 1 

像@Ylisar表示,* TOI函數用於將數字值從字符串轉換爲整數變量。

以下代碼將輸出數字表示,但請注意const變量的指針表示形式。我已經離開了兩個版本,所以你可以看到其中的差別:

printf("TEST 1: %d \n", _tstoi(_T("1"))); 
    printf("TEST a: %d \n", _tstoi(_T("a"))); 
    WCHAR* b(_T("b")); 
    printf("TEST A: %d \n", _T("A")); 
    printf("TEST b: %d \n", *b); 

輸出:在多http://msdn.microsoft.com/en-us/library/yd5xkb5c%28v=vs.80%29.aspx

如果要總結(累加)的值

TEST 1: 1 
TEST a: 0 
TEST A: 13457492 
TEST b: 98 

退房,我建議你檢查一下在這些事情上做出奇蹟的STL範圍函數。例如

#include <numeric> 
#include <string> 

printf("TEST a: %d \n", *_T("a")); // 97 
printf("TEST b: %d \n", *_T("b")); // 98 

wstring uString(_T("ba")); 
int result = accumulate(uString.begin(), uString.end(), 0); 
printf("TEST accumulated: %d \n", result); 

結果:

TEST a: 97 
TEST b: 98 
TEST accumulated: 195 

這種方式,你不必有,遍歷所有的值去。範圍函數真的很適合這樣的東西。

簽出更多的:http://www.sgi.com/tech/stl/accumulate.html

+0

thx,笨拙地錯過了,更新了答案 – AzP

+0

+1 std :: accumulate –

0

的第一個問題,爲什麼的printf作爲intened已經被Ylisar回答不起作用。關於總結一個字符的十六進制表示的另一個問題稍微複雜一點。使用_tstoi()函數將字符串轉換爲數字值將僅在給定字符串表示像「123」這樣的數字轉換爲123時才起作用。您需要的是字符表示的總和。

在Unicode代碼點低於0x7F(0 ... 127)的情況下,這只是1 Byte UTF-8表示的總和。但是,在使用UNICODE標誌編譯的Windows上,每個字符表示使用2個字節。在調試器中運行以下代碼將解決這個問題。

// ASCII 1 Byte per character 
const char* letterA = "A"; 
int sumOfLetterA = letterA[0] + letterA[0]; // gives 130 

// 2 Bytes per character (Windows) 
const wchar_t* letterB = TEXT("B"); 
int sumOfLetterB = letterB[0] + letterB[0]; // gives 132 
+0

Windows _always_對WCHAR使用2字節的Unicode表示,而_always_使用1字節的ASCII +對'char'進行編碼。 'UNICODE'宏改變了'TCHAR' typedef和一堆函數宏。 – MSalters

+0

是的我知道,我不夠精確,但正如我所提到的「用UNICODE標誌編譯」,並假設該字符串是用宏L()或T()窗口字符之一生成的字符長度爲2個字節。 –

相關問題