printf неизвестный спецификатор% S - PullRequest
2 голосов
/ 19 сентября 2011

Я пытаюсь заставить пример кода работать, и он использует следующие строки:

   WCHAR cBuf[MAX_PATH];

    GetSharedMem(cBuf, MAX_PATH);

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

get shared 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 Studio, не знаю, как проверить мои параметры

Ответы [ 2 ]

3 голосов
/ 19 сентября 2011

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

Неквалифицированные строковые спецификаторы (большой% S)

В этих таблицах показано, как Windows и ANSI обрабатывают параметры на основе спецификатора% S и стиля вызова функции (одиночный, универсальный или широкий):

    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, и Windows рассматривают% S в основном как противоположность% s с точки зрения одного байта или ширины, что по иронии судьбы означает, что Windows и ANSI снова обрабатывают эти спецификаторы по-разному.

Обратите внимание, что ANSI по существу всегда обрабатывает% S так же, как% ls, другими словами, он всегда считается широкой строкой.

Windows, с другой стороны, обрабатывает% S по-разномув зависимости от типа вызова функции.Для однобайтовых вызовов функций% S действует как широкий спецификатор% ls, но для широких вызовов функций% S действует как однобайтовый спецификатор% hs.

Этот спецификатор не следует использовать для общих вызовов Windows.Поскольку% S является "противоположностью"% s, параметр должен быть широким, если флаг _UNICODE выключен, и однобайтовым, если флаг _UNICODE включен.Универсальный тип TCHAR не работает таким образом, и тип данных «anti-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: точный / Zc: wchar_t / Zc: forScope /Yu"StdAfx.h "/Fp"Debug\TestWchar.pch" / Fa "Debug \" / Fo "Debug \" /Fd"Debug\vc100.pdb "/ Gd / analysis- / errorReport: очередь

1 голос
/ 19 сентября 2011

Для печати широкой строки:

wchar_t * str = /*...*/

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