- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我的问题与这个旧问题有关 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 完全改变了答案,我也会使用 C++11,而且我确实可以访问 boost 库,尽管我不想使用它们。
最佳答案
这是一个 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]
In translation phase 6 (2.2), adjacent string literals are concatenated. If both string literals have the same encoding-prefix, the resulting concatenated string literal has that encoding-prefix. If one string literal has no encoding-prefix, it is treated as a string literal of the same encoding-prefix as the other operand.
...
通常,您可以使用预处理器通过使用标记连接来加宽字符串。例如,定义一组这样的宏
#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"
或使用您展示的运行时转换解决方案。
关于c++ - 如何将 uint16_t 转换为宽字符串 (std::wstring),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27909861/
我是一名优秀的程序员,十分优秀!