【问题标题】:Get_s function not workingGet_s 功能不工作
【发布时间】:2017-02-20 05:08:47
【问题描述】:

我的书说get_s() 函数是gets() 函数的更好替代品,gets() 函数已弃用且不应使用。但是,当我尝试使用 get_s() 函数时,它总是给我一个错误:

undefined reference to gets_s

This page says something about the gets_s,我不太了解它在ISO/IEC 99 中定义的函数。它不应该适用于所有编译器吗?我很确定我使用的是最新版本的 MinGW 编译器。

我应该如何使用这个功能?是使用gets()scanf()(而不是scanf_s()),还是fgets() 而不是fgets_s(),不好?

【问题讨论】:

  • “它不应该适用于所有编译器吗”。不,它不是标准的 C 函数。它是微软特有的,所以基本上需要 Visual Studio。
  • @kaylum,“ANSI C”与“微软特定”标准不同吗?
  • @kaylum,不了解这个标准可以吗?如何获取有关可用标准的典型数量的更多信息?
  • gets_s() 在 C11 (ISO/IEC 9899:2011) 标准的可选附件 K 中定义。它之前在TR 27431-1 中定义。它由 Microsoft 实现并作为标准提供,但 Unix (POSIX) 社区并没有留下深刻的印象。 C11 未标准化 gets() 函数——它不再是标准 C 的一部分,尽管所有实现都可能出于“向后兼容性”的原因提供它。它是never safe to use gets()。如果可用,gets_s() 可以。
  • 你必须知道你工作的环境——是的。他们都是不同的。了解核心 C 标准有很大帮助,但您最终也会使用非标准函数。如果您知道何时使用“非标准”功能,这会有所帮助。 C11 的附录 K 是可选的,不是“核心 C 标准”。直到最近,很多 MS C 支持坚定地是 C90,甚至不是 C99。情况有所改善,但还没有。 MS 有自己的标准岛。 Unix(包括 Linux)具有 POSIX 以提供许多共性,但在该标准之外存在差异。是的,你学到了很多。

标签: c mingw-w64 c11 gets tr24731


【解决方案1】:

是的,你是对的#bumblebee gets() 函数不执行边界检查,因此该函数极易受到缓冲区溢出攻击。它不能安全使用(除非程序在限制标准输入上出现的内容的环境中运行)。出于这个原因,该功能已在 C99 标准的第三次勘误中被弃用,并在 C11 标准中完全删除。 fgets() 和 gets_s() 是推荐的替代品。 永远不要使用gets()。

来源:http://en.cppreference.com/w/c/io/gets 检查天气,您包含相应的标题。还有一件事你必须看到的是,天气你的 c 编译器版本是更新版本或旧版本,也会产生问题。所以尝试使用 c11 标准或 c11 在线编译器

【讨论】:

  • @BumbleBee:MinGW 不是编译器;这是一个环境。 MinGW 提供的 C 编译器是 GCC。 GCC 是一个 C11 编译器,但 MinGW 环境主要基于微软的库。由于gets_s()是MS提供的,所以很奇怪你没有链接成功。我不确定我能否帮助解决链接失败的原因。
  • 我建议您在在线 c11 标准编译器上尝试相同的程序并检查其是否工作
  • 不知道;我从来没有使用过MinGW,也不知道它有什么版本的GCC,等等。我理论上知道MinGW是什么。
  • 我认为这可能会对您有所帮助stackoverflow.com/questions/16136142/…
  • @BumbleBee:我不知道这样的页面,不。太多系统中的可选位太多,这样一个页面不容易创建或维护。
【解决方案2】:

在 90 年代初左右,gets() 被发现存在设计缺陷,因为它会一直读取数据直到找到字符串的结尾,这意味着它可能会意外或通过安全漏洞导致缓冲区溢出。

因此,gets 在 C99 标准中被标记为过时的函数。这意味着从 1999 年开始,人们被警告不要使用它。

该功能已从 C11 标准中的语言中完全删除,这意味着有不少于 12 年的非常慷慨的过渡期来修复遗留代码。它被 gets_s 取代,作为将旧代码移植到 C11 时使用的安全替代方案。它将缓冲区大小作为第二个参数。

但是,gets_s 应该仅用于此类 C11 移植原因,如果有的话。 gets_s 是 C11 中可选边界检查接口的一部分,编译器不需要实现它。 C11 标准建议改用fgets

推荐做法
fgets 函数允许正确编写 安全处理输入行的程序太长而无法存储在结果中 大批。一般来说,这需要 fgets 的调用者注意 结果数组中是否存在换行符。 考虑使用 fgets(以及任何需要的基于 换行符)而不是 gets_s


请注意,gets_s 与非标准 Visual Studio 编译器几乎没有关系,即使该编译器恰好支持此功能,就像支持边界检查接口 (__STDC_LIB_EXT1__) 的符合标准的编译器一样.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-13
    • 1970-01-01
    • 2017-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多