我的问题与这个较老的问题有关 Format specifiers for uint8_t, uint16_t, ...?
回顾原始问题是关于如何使用uint8_t,uint16_t,uint32_t和uint64_t与scanf的说明符?
问题的答案如下:
sscanf (line, "Value of integer: %" SCNd32 "\n", &my_integer);
但有没有人知道如何做到这一点,但会产生一个宽字符串?
即
std::wstring line;
swscanf (line.c_str(), L"Value of integer: %" SCNd16 L"\n", &my_integer);
sbove行给了我一个连接错误。我相信因为SCNd16不是用于广泛的?
目前我的解决方案是在原始答案中创建std :: string,然后将其转换为宽字符串
sscanf_s(line.c_str(), "%" SCNd16 "\n", &sixteenBitInteger)
// code here to check for EOF and EINVAL
//then I convert it
typedef std::codecvt_utf8<wchar_t> ConverterType;
std::wstring_convert<ConverterType, wchar_t> converter;
std::wstring convertedString = converter.from_bytes(line);
但它相当难看,我相信必须有一个更加精致的方式来进行这种转换? 如果它有助于理解我的使用,我使用uint16_t类型来存储Web服务器的端口号,但我希望能够将它转换为宽字符串,因为这是预期的显示类型。我也在使用C ++ 11,如果它改变了答案,我可以访问boost库,但我宁愿不使用它们。
答案 0 :(得分:4)
这是VS2013 compiler bug。由于它已被关闭为“固定”,它可能在VS2015中工作(没有安装预览试试)。
您拥有的代码行
swscanf (line.c_str(), L"Value of integer: %" SCNd16 L"\n", &my_integer);
格式正确,因为即使SCNd16
扩展为缺少L
前缀的字符串文字,标准也会说如果两个相邻的字符串文字中缺少一个编码前缀,则它是视为具有与另一个相同的编码前缀。
§2.14.5/ 14 [lex.string]
在翻译阶段6(2.2)中,连接相邻的字符串文字。如果两个字符串文字具有相同的 encoding-prefix ,则生成的连接字符串文字具有 encoding-prefix 。如果一个字符串文字没有 encoding-prefix ,则将其视为与另一个操作数相同的 encoding-prefix 的字符串文字。
...
通常,您可以使用预处理器通过使用标记连接来扩展字符串。例如,定义一组像这样的宏
#define WIDEN_(x) L##x
#define WIDEN(x) WIDEN_(x)
并将有问题的代码行转换为
swscanf (line.c_str(), L"Value of integer: %" WIDEN(SCNd16) L"\n", &my_integer);
会解决问题,但由于实现细节,它不会在VS2013上解决。 SCNd16
宏实际上扩展为两个单独的字符串文字 - "h" "d"
。所以上面的宏扩展了第一个文字,但不是第二个,你遇到了同样的(假的)错误。
您的选择是对字符串"hd"
进行硬编码,或者使用您显示的运行时转换解决方案。
答案 1 :(得分:0)
一个纯粹的猜测,因为我现在没有时间尝试它。
您是否可以使用preprocesser将宽字符串L标记粘贴到展开的SCNd16的前面?