如何定义 SCANF 以后成为安全函数 scanf_s()?

How to define SCANF to later be the secure function scanf_s()?

提问人:Assel 提问时间:10/14/2023 更新时间:10/14/2023 访问量:115

问:

我被布置了家庭作业,我需要编写一个 C 程序,首先从用户那里读取两个浮点数。如果您的编译器支持安全函数,我需要使用 scanf_s() 函数来读入,使用 #if ...#else ...#endif 指令。 作业表说我必须将 SCANF 定义为安全函数 scanf_s() 并添加一个 else 部分以将 SCANF 定义为标准函数 scanf(),但我真的不明白这意味着什么。有人可以向我解释一下吗?

我只是不明白问题陈述的含义。

c 扫描

评论

4赞 Barmar 10/14/2023
老师没有教过什么吗?
3赞 Barmar 10/14/2023
scanf()并且不可互换,它们采用不同的论点。不能使用宏来模拟此情况。scanf_s()
1赞 JohnFilleau 10/14/2023
@Barmar 和之间的不同接口比检查 更重要。你是对的。他们真的需要和他们的教学人员谈谈这个问题。scanfscanf_s__STDC_LIB_EXT1__
2赞 Barmar 10/14/2023
@JohnFilleau OTOH 中,不同的接口仅在读取字符串时适用,是相同的。%f
1赞 zwol 10/14/2023
根本不应该使用附件K的任何功能,因为它们是不可移植的,实际上并不能解决它们打算解决的问题。此外,scanf 本身已按指定损坏,也不应使用。这是一项糟糕的作业,你可以告诉你的导师我是这么说的。

答:

3赞 Oka 10/14/2023 #1

系统指示您使用预处理器指令有条件地定义一个文本替换宏,该宏将标记替换为 或 ,具体取决于前者的可用性。SCANFscanf_sscanf

请注意,以下通常是一个糟糕的想法,因为变量参数接受 AND 有很大差异,具体取决于所使用的格式说明符。下面我们只使用 ,它恰好在两个函数之间工作相同。例如,在下面的程序中使用 ,将调用 Undefined Behaviourscanfscanf_s%f%s

scanf_s的一些文档中:

与所有边界检查函数一样,仅当实现定义了 ,并且用户在包含 之前定义了整数常量时,才能保证 和 可用。scanf_sfscanf_ssscanf_s__STDC_LIB_EXT1____STDC_WANT_LIB_EXT1__1<stdio.h>

#ifdef __STDC_LIB_EXT1__
#define __STDC_WANT_LIB_EXT1__ 1
#define SCANF scanf_s
#else
#define SCANF scanf
#endif

#include <stdio.h>

int main(void)
{
    float a, b;

    printf("Enter two floating-point numbers: ");

    if (2 != SCANF("%f%f", &a, &b)) {
        fputs("Could not read input.\n", stderr);
        return 1;
    }

    printf("Got: [%.2f], [%.2f]\n", a, b);
}

评论

0赞 Ian Abbott 10/14/2023
错别字:应该是 .#define __STDC_WANT_LIB_EXT1 1#define __STDC_WANT_LIB_EXT1__ 1
0赞 Assel 10/14/2023
谢谢。现在我更清楚了
0赞 Oka 10/14/2023
@IanAbbott Cheers,盲目地从上面的评论中复制了他们的大纲。