虽然装好了 Clion 也配置好了 Mingw ,但是在 Windows 平台下还是比较习惯使用 VS。

今天最奇葩的问题就是在机房上 VS2010 + 学校的 Online Judge系统(gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5 ,C99) 上编译通过的程序在 VS2017 不能正常运行。

众所周知 M$ 在 Visual Studio 2017 中强制要求使用 scanf_s (线性安全输入)来避免内存访问越界的问题,所以我的代码如下

scanf_s("%f%c%f", &a, &f, &b);

逐过程调试到输入数据后就提示 “(ucrtbased.dll)处 引发的异常: 0xC0000005: 写入位置 0x001D105A 时发生访问冲突。”,同时在编译日志中也找到了一些蛛丝马迹

warning C4473: “scanf_s”: 没有为格式字符串传递足够的参数
note: 占位符和其参数预计 4 可变参数,但提供的却是 3 参数
缺失的可变参数 4 为格式字符串“%f”所需

原来是指针越界了。相比 scanf 为了线性安全,scanf_s 要求在录入字符串的时候都要指定缓冲区的大小。所以解决方案就是指定缓冲区的大小。代码修改如下

scanf_s("%f%c%f", &a, &f,4, &b);

不同的编译器有不同的要求,若编译器没有要求在强制使用线性安全函数,直接用 scanf 进行输入即可。

最后,M$ 官方也给出了相应的英文文档,水平不足就不做翻译了,蛮看看能理解就好。