I am trying to parse following string- "DATA,97,103,100,97,84,69"
. This string can have following varieties-
"DATA,100,10,1,9,82,60"
"DATA,57,27,59,30,11,64"
"DATA,12,86,100,97,103,23"
"DATA,1,10,78,38,45,52"
"DATA,99,43,85,28,84,26"
Note that the first "DATA,"
never changes. The remaining integer numbers varies from 0 to 200. Below is the code which uses sscanf_s
function to parse these strings-
char ignore_data[5];
int x1,x2,x3,y1,y2,y3;
char str[]="DATA,97,103,100,97,84,69";
sscanf_s(str,"%5[^,],%d,%d,%d,%d,%d,%d", ignore_data, &x1, &x2, &x3, &y1, &y2, &y3);
printf("str=%s, x1=%d, x2=%d, x3=%d, x1=%d, y2=%d, y3=%d",str, x1, x2, x3, y1, y2,y3);
The code does not work and shows following error
Unhandled exception at 0x510A06E4 (msvcr110d.dll) in My Application.exe: 0xC0000005: Access violation writing location 0x00870000.
The above code works perfectly, when sscanf()
is used with #define _CRT_SECURE_NO_WARNINGS
preprocessor.
I want to get the values of x1
, x2
, x3
, y1
, y2
and y3
. What am I missing here?
I found that if you are able to implement the following you should be able to get the results you need:
#include <stdio.h>
int main()
{
char ignore_data[5];
int x1, x2, x3, y1, y2, y3;
char str[] = "DATA,97,103,100,97,84,69";
sscanf_s(str, "%5[^,],%d,%d,%d,%d,%d,%d", ignore_data, sizeof(ignore_data), &x1, &x2, &x3, &y1, &y2, &y3);
printf("str=%s, x1=%d, x2=%d, x3=%d, x1=%d, y2=%d, y3=%d", str, x1, x2, x3, y1, y2, y3);
return 0;
}
For sscanf_s
when taking in a string, immediately after scanning the data you will need the size of the destination buffer. This helps in making a secure port between the input stream (whatever it may be) to the destination, reducing the possibility of buffer overflow when accepting strings.
As Cremno pointed out it will need to be sscanf_s(str, "%5[^,],%d,%d,%d,%d,%d,%d", ignore_data, (unsigned)sizeof(ignore_data), &x1, &x2, &x3, &y1, &y2, &y3);
The attention given to the fact that the the sizeof(ignore data)
should return an unsigned value.
Quoting the C11
standard, Annex K, Chapter §K.3.5.3.2, The fscanf_s()
function , ( emphasis mine )
The
fscanf_s()
function is equivalent tofscanf()
except that thec
,s
, and[
conversion specifiers apply to a pair of arguments (unless assignment suppression is indicated by a *) . The first of these arguments is the same as forfscanf()
. That argument is immediately followed in the argument list by the second argument, which has typersize_t
and gives the number of elements in the array pointed to by the first argument of the pair. [...]
Now, coming to the scope of sscanf_s()
, chapter §K.3.5.3.7
The
sscanf_s
function is equivalent tofscanf_s
, except that input is obtained from a string (specified by the arguments
) rather than from a stream. [...]
Hope the above text is enough to point out the error, you're missing the second argument required for [
, present in the format string. You need to supply the size for ignore_data
, as rsize_t
type.
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.