fscanf / fscanf_s 行为差异

发布于 2024-09-07 02:19:37 字数 513 浏览 2 评论 0原文

我对以下行为差异感到困惑:

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

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

谢谢!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

星光不落少年眉 2024-09-14 02:19:37

来自 fscanf_s() 上的文档,http:// msdn.microsoft.com/en-us/library/6ybhk9kc.aspx

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

以及http://msdn.microsoft.com/en-us/library/w40768et。 ASPX

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

字符[10];

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

所以你应该这样称呼它:

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

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));
傲影 2024-09-14 02:19:37

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

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

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);
成熟的代价 2024-09-14 02:19:37

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

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

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;
善良天后 2024-09-14 02:19:37

我认为有可能会产生误导结果:

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

相反,它应该是这样的:

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

其中 countof(cmd) 是分配给 cmd 的内存块的总大小,它必须大于 80,sizeof( cmd) 将为 4 或 8,在这种情况下会出错。

I think there is a chance of misleading result in:

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

Instead it should be like:

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

where countof(cmd) is total size of memory block allocated to cmd which must be greater than 80, sizeof(cmd) would be either 4 or 8 which will give error in the case.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文