C++ fscanf / fscanf_s 行为差异

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3112869/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 12:04:57  来源:igfitidea点击:

fscanf / fscanf_s difference in behaviour

c++visual-c++visual-studio-2005crt

提问by Ofek Shilon

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?

结果不依赖于调用顺序(即首先调用 fscanf_s,您将首先获得空字符串)。在 VC++ - VS2005 上编译。任何人都可以复制吗?谁能解释一下?

Thanks!

谢谢!

回答by Michael Burr

From the docs on fscanf_s(), http://msdn.microsoft.com/en-us/library/6ybhk9kc.aspx:

从文档上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.

安全函数(带有 _s 后缀)与旧函数之间的主要区别在于,安全函数要求将每个 c、C、s、S 和 [ 类型字段的大小作为紧跟在变量之后的参数传递。有关详细信息,请参阅 scanf_s、_scanf_s_l、wscanf_s、_wscanf_s_l 和 scanf 宽度规范。

And http://msdn.microsoft.com/en-us/library/w40768et.aspx:

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);

与 scanf 和 wscanf 不同,scanf_s 和 wscanf_s 要求为 c、C、s、S 或 [ 类型的所有输入参数指定缓冲区大小。缓冲区大小作为附加参数传递,紧跟在指向缓冲区或变量的指针之后。例如,如果读取一个字符串,则该字符串的缓冲区大小按如下方式传递:

字符 [10];

scanf("%9s", s, 10);

So you should call it like so:

所以你应该这样称呼它:

fscanf_s(fp,"%80s",cmd, sizeof(cmd));

回答by Michael Mrozek

fscanf_s(and the whole scanf_sfamily) requires that you pass the size of any %c, %C, %s, %S, or %[after the buffer itself; you're omitting that argument:

fscanf_s(以及整个scanf_s系列)要求您传递任何%c, %C, %s, %S, 或%[缓冲区本身之后的大小;你忽略了这个论点:

fscanf_s(fp, "%80s", cmd, 81);

回答by Puppy

Your question is tagged C++ and you're compiling in VC++, but using fscanf? Get a std::ifstream.

您的问题被标记为 C++ 并且您正在 VC++ 中进行编译,但是使用 fscanf?获取 std::ifstream。

std::string buffer;
std::ifstream fp("my filepath");
fp >> buffer;