fscanf / fscanf_s difference in behaviour
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!
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);
Your question is tagged C++ and you're compiling in VC++, but using fscanf? Get a std::ifstream.
std::string buffer;
std::ifstream fp("my filepath");
fp >> buffer;
精彩评论