I'm puzzled by the following difference in behaviour:
// suppose myfile.txt contains a single line with the single character 's'
errno_t res;
FILE* fp;
char cmd[81];
res = fopen_s(&fp, "D:\\myfile.txt", "rb" );
fscanf(fp,"%80s",cmd); // cmd now contains 's/0'
fclose(fp);
res = fopen_s(&fp, "D:\\myfile.txt", "rb" );
fscanf_s(fp,"%80s",cmd); // cmd now contains '/0' !
fclose(fp);
The results do not depend in the order of call (i.e., call fscanf_s first, you'd get the empty string first). Compiled on VC++ - VS2005. Can anyone reproduce? Can anyone explain?
Thanks!
Each call to fscanf() reads one line from the file.
The fscanf() function reads data from the current position of the specified stream into the locations that are given by the entries in argument-list, if any. Each entry in argument-list must be a pointer to a variable with a type that corresponds to a type specifier in format-string.
scanf originally just reads whatever console input you type and assign it to a type of variable. scanf_s has an parameter, When you read a string, the parameter must be provided to indicate how many characters are read at most to prevent overflow.
From the docs on fscanf_s()
, http://msdn.microsoft.com/en-us/library/6ybhk9kc.aspx:
The main difference between the secure functions (with the _s suffix) and the older functions is that the secure functions require the size of each c, C, s, S and [ type field to be passed as an argument immediately following the variable. For more information, see scanf_s, _scanf_s_l, wscanf_s, _wscanf_s_l and scanf Width Specification.
And http://msdn.microsoft.com/en-us/library/w40768et.aspx:
Unlike scanf and wscanf, scanf_s and wscanf_s require the buffer size to be specified for all input parameters of type c, C, s, S, or [. The buffer size is passed as an additional parameter immediately following the pointer to the buffer or variable. For example, if reading a string, the buffer size for that string is passed as follows:
char s[10];
scanf("%9s", s, 10);
So you should call it like so:
fscanf_s(fp,"%80s",cmd, sizeof(cmd));
fscanf_s
(and the whole scanf_s
family) requires that you pass the size of any %c
, %C
, %s
, %S
, or %[
after the buffer itself; you're omitting that argument:
fscanf_s(fp, "%80s", cmd, 81);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With