2011-09-19 83 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