How to convert uint16_t to wide string (std :: wstring)

My question is related to this old question Format specifiers for uint8_t, uint16_t, ...?

Just to repeat the original question, was it related to how to use specifiers for uint8_t, uint16_t, uint32_t and uint64_t with scanf?

The answer to the question was as follows:

sscanf (line, "Value of integer: %" SCNd32 "\n", &my_integer);

      

But does anyone know how to do this, but the result is a wide string?

t

std::wstring line;
swscanf (line.c_str(), L"Value of integer: %" SCNd16 L"\n", &my_integer);

      

The sbove line is giving me a concatenation error. I believe because SCNd16 is simply not meant to be extensible?

My solution currently is to create a std :: string in the original answer and then convert it to a wide 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);

      

but this is pretty ugly and I'm sure there must be a more polished way to do this conversion? If it helps to understand my usage, I am using the uint16_t type to store the port number for the webserver, but I want it to be able to convert it to a wide string since that is the expected display type. I also use C ++ 11, if that changes the answer at all, and I have access to the boost libraries, although I would rather not use them.

+3


source to share


2 answers


This is a VS2013 compiler error . Since it was closed as "patched", it will probably work in VS2015 (it doesn't have a preview to try).

In a line of code, you have

swscanf (line.c_str(), L"Value of integer: %" SCNd16 L"\n", &my_integer);

      

is well formed because even if it SCNd16

expands to a string literal that does not have a prefix L

, the standard says that if an encoding prefix is โ€‹โ€‹missing from two adjacent string literals, it is treated as if it has the same encoding prefix as the other.

ยง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 does not have an encoding prefix, it is treated as a string literal with the same encoding prefix as the other operand....




Typically, you can use a preprocessor to expand strings using token concatenation. For example defining a set of macros like this

#define WIDEN_(x) L##x
#define WIDEN(x) WIDEN_(x)

      

and converting the breaking code line to

swscanf (line.c_str(), L"Value of integer: %" WIDEN(SCNd16) L"\n", &my_integer);

      

will fix the problem, but not on VS2013 due to implementation detail. The macro SCNd16

actually expands into two separate string literals - "h" "d"

. So the above macro expands the first literal but not the second, and you run into the same (dummy) error.

Your options are to either copy the line "hd"

or go with the suggested runtime runtime solution.

+4


source


Pure guesswork as I don't have time to try it.



Can you use a token preprocessor to insert a widescreen L at the front of the extended SCNd16?

0


source







All Articles