std::smatch match;
...
TRACE("%s\n",match[0]); // this outputs some garbage like this '˜ò'
The %s
type specifier in the TRACE
macro expects a raw C string pointer (char*
in ANSI/MBCS builds; wchar_t*
in Unicode builds - I'm assuming you are doing an ANSI/MBCS build here.).
But match[0]
is not a raw C string pointer.
So you have a mismatch between what you promised to TRACE
via %s
(i.e. a raw C string char*
pointer), and what you are actually passing to it (i.e. match[0]
).
According to some online documentation, std::smatch
is a specialization of the std::match_results
template, in particular:
smatch --> match_results<string::const_iterator>
smatch::operator[]
(which you are invoking in your code as match[0]
) returns a reference to another object, which is a std::sub_match
.
This std::sub_match
class represents a pair of iterators, denoting sequences of matched characters.
So, you are promising to TRACE
to pass a raw C string pointer (via the %s
type specifier), but you are actually passing a completely different thing, i.e. a reference to a std::sub_match
object (via your match[0]
code): no wonder that the printed text is meaningless.
What you have to do is to obtain a C string pointer from the match[0]
expression.
To do that, you can invoke the std::sub_match
's str()
method. This returns a std::string
object.
However, this std::string
object is not exactly what %s
expects: in fact, %s
represents a raw C string pointer (e.g. const char*
), not a std::string
instance.
So, the last step is to extract this raw C string pointer from the std::string
object, and this is done by invoking the std::string::c_str()
method.
To summarize these logical steps:
std::smatch match;
...
match[0] --> reference to std::sub_match object
match[0].str() --> std::string object
match[0].str().c_str() --> raw C string pointer (const char*)
So, your TRACE
statement can be written as:
TRACE("%s\n", match[0].str().c_str());