2015-03-13 131 views
3

我包括我的.cpp程序下列文件:C++字符串類型混淆

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

然而,當我寫

LPCTSTR pMsg; 
DWORD msgLen; 
... 
msgLen = _tcslen(pMsg); 

編譯器會提示以下錯誤:

C2664: 'size_t strlen(const char *)' : cannot convert argument 1 from 'LPCTSTR' to 'const char *' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

當然,我可以通過鑄造到LPCSTR或使用wcslen。但是,這是不對的,不應該編譯器決定所有的東西本身,取決於宏UNICODE?這當然是有定義的,因爲當我在文件開頭寫#define UNICODE時,編譯器會提示警告,說它已經被定義。那麼問題是什麼?爲什麼它選擇strlen而不是wcslen

下面是實際的代碼:

BOOL PrintString(HANDLE hOut, ...) 
{ 
    DWORD msgLen, count; 
    LPCTSTR pMsg; 
    va_list pMsgList; 
    va_start(pMsgList, hOut); 
    while((pMsg = va_arg(pMsgList, LPCTSTR)) != NULL) 
    { 
     msgLen = _tcslen(pMsg); 
     if(!WriteConsole(hOut, pMsg, msgLen, &count, NULL) && !WriteFile(hOut, pMsg, msgLen*sizeof(TCHAR), &count, NULL)) 
     { 
      va_end(pMsgList); 
      return FALSE; 
     } 
    } 
    va_end(pMsgList); 
    return TRUE; 
} 

我都嘗試,#define _UNICODE#define _UNICODE但也沒有幫助。此外,#define _UNICODE會提示已被定義的警告。

+0

根據[文檔](https://msdn.microsoft.com/en-us/library/c426s321.aspx),控制宏是'_UNICODE',而不是'UNICODE'。你有這個定義正確嗎? – Angew 2015-03-13 08:23:26

+0

是的,我試着在.cpp文件的開頭定義'UNICODE'和/或'_UNICODE',但它沒有幫助 – nicks 2015-03-13 08:25:10

+0

你有沒有計劃使用MBCS或SBCS?如果沒有,你可以擺脫整個tchar業務並明確使用'wchar_t'。 – Angew 2015-03-13 08:30:09

回答

4

根據MSDN,_tcslen擴展到的是由宏_UNICODE控制。另一方面,LPCTSTRUNICODE控制。確保你有一致地定義這兩個宏,並且在任何可能使用它們的頭部被包含之前。

+0

請參閱定義unicode的編輯 – nicks 2015-03-13 08:31:15

+0

@NikaGamkrelidze您的VS項目設置(在項目屬性中)是否還包含unicode? – Angew 2015-03-13 08:33:51

+0

'之前的任何標題'<<真的有把戲。包含後我正在定義_UNICODE。但爲什麼這是必要的?這些標題不應該自己定義它嗎? – nicks 2015-03-13 08:35:20

2

_tcslen正在擴大到strlenLPCTSTR正在擴大到const wchar_t*。這意味着你有_UNICODEUNICODE定義不一致。前者由TCHAR頭文件使用,後者由Windows頭文件使用。鑑於您的更新問題,我會說你有UNICODE定義和_UNICODE未定義。

除此之外,你不應該使用TCHAR讓你的生活變得更容易。當你需要爲Win9x和WinNT編譯單個源代碼時,這很有用。如今,你大概不會針對Win9x。所以我的建議是簡單地刪除所有使用TCHAR,並讓你的代碼更簡單。

+0

請參閱編輯實際代碼 – nicks 2015-03-13 08:27:32