Click here to Skip to main content
15,881,173 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
In a simple code, I have the conversion problem, and get the above error,but don't understand why! Any thoughts..
C++
CString s ="first:25.5,second,15";
if ( swscanf_s(s, "%s %f %s %d", &st1, &doub, &st2, &integ )!= 4 )
Posted

It looks like you're mixing your character types up - swscanf_s expects wide character arguments and the version of CString you're using uses narrow characters.

If you really have to use CString and swscanf_s then make sure you've defined all the preprocessor stuff you need to make sure that CString is compiled as the wide character version. Try defining UNICODE and _UNICODE on your compiler command line.

However, as soon as you do that your declaration of the string to be parsed will all go to pot - you need to stick an L before the start of the literal string you use to initialise the string:
C++
CString s =L"first:25.5,second,15";
or use the ghastly _T macros that Microsoft introduced in about 1994:
C++
CString s = _T("Your guff in here...");


If you can't define _UNICODE or UNICODE then perhaps change the function you're using to sscanf instead - which deals with narrow arrays.

Oh, and when you do sort out the types you'll probably find it won't work the way you want it to either. But that's another problem :-)

[Your format string looks like it's for sscanf, not swscanf_s and as there's no white space between fields you're probably going to read everything into the first character buffer.]
 
Share this answer
 
Comments
Nithin Sundar 28-May-12 7:57am    
Deserves a 5 and a best answer winner hands down.
Sandeep Mewara 28-May-12 8:34am    
5+!
stib_markc 29-May-12 1:34am    
5!
Sumal.V 29-May-12 4:18am    
Thanks so much.. Have to get some tuitions from you ;)
JackDingler 29-May-12 16:59pm    
Make it a CStringW and it won't matter what the preprocessor definitions are.
The deciding line is

if ( swscanf_s(s, L"%s %f %s %d", &st1, &doub, &st2, &integ )!= 4 )


As Nithin has written in his post, the second argument needs to be a wide character string and hence the L"... is required.

All other suggestions are more or less useless. For example, the line

CString s ="first:25.5,second,15";


it okay, because the CString knows how to convert from a char string to a wide-char string. All is ok there.

There are however a couple of other quirks in this example. First of all, if you are using swscanf_s the string arguments require an additional specifier of the buffer length. For example:

wchar_t st1 [50];
wchar_t st2 [50];
if (swscanf_s(s, L"%s %f %s %d", &st1, 50, &doub, &st2, 50, &integ )!= 4 )


Next, your input does not really match the format specifier. The %s consumes all characters up to the next white space. Hence you better change the input to:

CString s ="first 25.5 second 15";


And finally, if doub is a double variable, you should specify "%lf" as format specifier, otherwise swscanf_s assumes that you are passing the address of a float variable.

With all these changes the example will run as expected.
 
Share this answer
 
Comments
Sumal.V 29-May-12 3:45am    
Thanks for the explanation, had many doubts regarding the sscanf, swscanf functions.
Sumal.V 29-May-12 4:10am    
Still have doubts on formatting a string.

char *tokenstring = "first 25.5,second 15";
result = sscanf(tokenstring, "%[^' '] %[^','],%[^' '] %s", string1, flt, string2, int1);

This is the right format for the given string, But don't understand why I must include the %[^' '] plus leave a space in between the next set of values in the string. And the last value in the string as %s! could you please give me few examples?
nv3 29-May-12 7:13am    
The [abc] notation is a rather new addition to sscanf formatting. Such a pair of brackets may be used in place of the 's' format type and means that a string is read as long as it contains characters inside the brackets. If the first character in the brackets is the circumflex '^' that means that the effect is negated, i.e. scanf read a string as long as it does NOT detect a character inside the bracket. Hence you could parse your original string with the specification: "%[^:]:%lf,%[^,],%d".

The format specification that you gave in your last comment looks incorrect to me; besides it does not even contain type specifiers for the double and int variables.

You might want to take a look at the documentation of sscanf, for example on the MSDN website.
Try converting your code:

C++
CString s ="first:25.5,second,15";
if ( swscanf_s(s, "%s %f %s %d", &st1, &doub, &st2, &integ )!= 4 )


to:

C++
CString s =_T("first:25.5,second,15");
if ( swscanf_s(s, _T("%s %f %s %d"), &st1, &doub, &st2, &integ )!= 4 )


or

CString s =L"first:25.5,second,15";
if ( swscanf_s(s, L"%s %f %s %d", &st1, &doub, &st2, &integ )!= 4 )



By the way I think it is because of a Unicode conversion issue. The _T will help your code automatically convert from Unicode and ANSI when they are required. You can still use L"This is a sample string" instead of _T("This is a sample string").
 
Share this answer
 
v2
Comments
Mohibur Rashid 28-May-12 9:23am    
_T is supported in VC6, as far I can recall it is obsolete now, Instead TEXT is available
Yes it was suppose to do that.
C++
//your code:
CString s ="first:25.5,second,15";
//Change it to 
CString s =L"first:25.5,second,15";
if ( swscanf_s(s, "%s %f %s %d", &st1, &doub, &st2, &integ )!= 4 )
 
Share this answer
 
Comments
Sumal.V 28-May-12 6:28am    
Nope It still shows the error:
Here's my code:

int main( void )
{
int integ ;
CString st2,st1;
float doub;

CString s =L"first:25.5,second,15";

if ( swscanf_s(s, "%s %f %s %d", &st1, &doub, &st2, &integ )!= 4 )
{
cout<< "right";
}
else
cout <<"wrong";
}
stib_markc 28-May-12 6:35am    
Try casting "s" with LPCTSTR; like this:
if(swscanf_s((LPCTSTR)s,....)
Sumal.V 28-May-12 6:44am    
That doesn't help too...
Mohibur Rashid 28-May-12 7:43am    
do you even try by yourself? did you even try to understand why I told you to add an L infront of the string? you didnt even ask what is that mean.
also change your swscanf_s function like below
swscanf_s(s, L"%s %f %s %d", &st1, &doub, &st2, &integ );
Nithin Sundar 28-May-12 7:49am    
I think an explanation is needed. Please look at my answer.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900