2011-09-19 57 views
2

我想獲得一個示例代碼的工作,它使用以下行:printf的未知說明符%S

WCHAR cBuf[MAX_PATH]; 

    GetSharedMem(cBuf, MAX_PATH); 

    printf("Child process read from shared memory: %S\n", cBuf); 

人分享MEM:

__declspec(dllexport) VOID __cdecl GetSharedMem(LPWSTR lpszBuf, DWORD cchSize) 
{ 
    LPWSTR lpszTmp; 

    // Get the address of the shared memory block 

    lpszTmp = (LPWSTR) lpvMem; 

    // Copy from shared memory into the caller's buffer 

    while (*lpszTmp && --cchSize) 
     *lpszBuf++ = *lpszTmp++; 
    *lpszBuf = '\0'; 
} 

奇怪的是我得到一個未知說明符錯誤printf行。 %S是一個MS擴展,而不是ANSI兼容,但我會認爲它會默認包含在內。我如何打開這個?

我使用Microsoft Visual工作室,不知道如何檢查我的選擇

+3

您使用的編譯器是什麼?有什麼選擇? – geoffspear

+0

'%S'應該做什麼? –

+0

@Kerrek SB:打印寬字符 – Joe

回答

3

http://www.globalyzer.com/gzserver/help/localeSensitiveMethods/formatting.htm#larges

不合格字符串說明符(大%S)

這些表顯示了Windows和ANSI如何根據%S說明符和函數調用樣式(單個基因RIC,或寬):

 
    Windows function    Specifier Parameter needs to be 
    printf/sprintf (single/MBCS) %S   wchar_t* 
    _tprintf/_stprintf (generic) %S   (don't use) 
    wprintf/swprintf (wide)   %S   char* 

    ANSI function     Specifier Parameter needs to be 
    printf/sprintf (single/MBCS) %S   wchar_t* 
    wprintf/swprintf (wide)   %S   wchar_t* 

ANSI和視窗治療%S基本上在單個字節或寬,這諷刺意味着Windows和ANSI再次不同的方式處理這些說明符的條款相對的%s。

請注意,ANSI本質上總是以與%ls相同的方式處理%S,換句話說它總是假定爲寬字符串。

另一方面,Windows根據函數調用的類型對待%S。對於單字節函數調用,%S的作用類似於寬的%ls說明符,但對於寬泛函數調用,%S的作用與單字節%hs說明符相同。

此說明符不應用於Windows通用調用。由於%S是%s的「反向」,因此如果_UNICODE標誌關閉,參數將需要較寬,如果_UNICODE標誌打開,則需要單個字節。 TCHAR泛型類型不能以這種方式工作,並且沒有「反TCHAR」類型的數據類型。

我嘗試以下在Visual C++ 2010:

#include "stdafx.h" 
#include <Windows.h> 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    WCHAR cBuf[MAX_PATH]; 
    TCHAR tBuf[MAX_PATH]; 

    wcsncpy_s(cBuf, L"Testing\r\n", MAX_PATH); 
    _tcsncpy_s(tBuf, _T("Testing\r\n"), MAX_PATH); 

    printf("%S", cBuf); // Microsoft extension 
    printf("%ls", cBuf); // works in VC++ 2010 
    wprintf(L"%s", cBuf); // wide 
    _tprintf(_T("%s"), tBuf); // single-byte/wide 

    return 0; 
} 

設置:

/ZI/NOLOGO/W3/WX-/ OD/Oy-/d 「WIN32」/ d 「_DEBUG」/D「_CONSOLE」/ D「_UNICODE」/ D「UNICODE」/ Gm/EHsc/RTC1/GS/fp:precise/Zc:wchar_t/Zc:forScope /Yu"StdAfx.h「/Fp"Debug\TestWchar.pch 「/ Fa」Debug \「/ Fo」Debug \「/Fd"Debug\vc100.pdb」/ Gd/analyze-/errorReport:隊列

+1

...爲什麼爲什麼... –

+0

我該如何關閉unicode標誌?現在窗戶沒有事件acccept%ls或%hs – mugetsu

+0

您正在使用哪個版本的Visual Studio? VC++ 2010支持%ls,但我不記得VC++ 6支持它。如果你想在早期版本中使用ANSI,你可能需要使用wprintf函數。 – nullforce

1

要打印寬字符串:

wchar_t * str = /*...*/ 

printf("The string: %ls\n", str); 
// or 
wprintf(L"The string: %ls\n", str); 
+0

嗯,我似乎得到一個錯誤,說L修飾符只對e,f,g說明符有效,這是與你的printf行 – mugetsu

+0

什麼是編譯器? '%Ls'格式說明符是標準的,但只有C99我想(當'wchar_t'被引入時)。等等,也許它是'%ls',小'l'。 –

+0

它應該是'%ls' – Joe