I don't understand why the code below fail :
char toto[54], titi[54]; //I already tried with allocations
sscanf_s(line, "%s-%s", &toto, &titi, sizeof(toto) + sizeof(titi));
or
sscanf_s(line, "%s-%s", &toto, &titi, sizeof(toto) + sizeof(titi));
My problem is only with strings (float, int, double etc. its ok) and I use Visual 2010.
Does anyone have an idea? Thanks a lot in advance for your answer.
From the sscanf_s()
reference page:
The sscanf_s function reads data from buffer into the location given by each argument. The arguments after the format string specify pointers to variables with a type that corresponds to a type specifier in format. Unlike the less secure version sscanf, a buffer size parameter is required when using the type field characters c, C, s, S and [. The buffer size in characters must be supplied as an additional parameter after each buffer which requires it. For more information, see scanf_s, _scanf_s_l, wscanf_s, _wscanf_s_l and scanf Type Field Characters.
Meaning each buffer must be followed by its size:
sscanf_s(line, "%s-%s", toto, sizeof(toto), titi, sizeof(titi));
Additionally, -
is not a whitespace character will not act as a terminator for "%s"
format specifier so if line
contained hello-world
then it would be read into toto
and titi
would not be assigned. To use -
as a terminator use a scan set:
if (2 == sscanf_s(line, "%[^-]-%s", toto, sizeof(toto), titi, sizeof(titi)))
{
/* Both 'toto' and 'titi' where assigned. */
}
Unless sscanf_s()
is distincly weird, you don't want to pass a pointer to the array ( &toto
) but a pointer to the first element of the array ( toto
). Also, the goal of the secure functions is to avoid buffer overruns, ie, you need to specify for each individual buffer how many characters it contains:
if (sscanf_s(line, "%s-%s", toto, sizeof(toto), titi, sizeof(titi)) == 2) {
...
}
(error handling because attempts to read should always check whether an error occured before processing the data)
Personally, I would use an std::istringstream
together with strings and a suitable custom manipulator and avoid the issue entirely:
std::istream& minus(std::istream& in) {
if ((in >> std::ws).peek() != std::char_traits<char>::to_int_type('-')) {
in.setstate(std::ios_base::failbit);
}
else {
in.ignore();
}
return in;
}
std::string toto, titi;
if (std::istringstream(line) >> std::skipws >> toto >> minus >> titi)) {
...
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.