【问题标题】:C99 - vscanf for dummies? [closed]C99 - 用于假人的 vscanf? [关闭]
【发布时间】:2013-06-05 17:19:56
【问题描述】:

很抱歉打扰 S.O.有了这样一个一般性的信息请求。

我可以找到很多非常多术语的 vscanf 定义 - 但我找不到太多具体示例来显示函数返回的内容,除了 IBM 信息中心上的这个非常不错的示例网站:

http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/index.jsp?topic=%2Frtref%2Fvscanf.htm

然而,这个例子仅适用于单行字符串输入,而我正在尝试做同样的事情,但从多行的 .txt 文件中读取。

我必须使用 fgets() 一次读取一行然后使用 vscanf 吗?我是否必须像 IBM 信息中心示例那样,通过将它放在函数 vread() 中来在函数中使用它?

我是 CS 一年级的学生,但这不是作业的问题,我只是想做一些额外的工作并扩展我的知识,我们还没有到 vread/vscanf。

我应该坚持使用 sscanf 吗?如果有这么愚蠢,我深表歉意。

附:我喜欢学习 C。我在这个星球上的 31 年中作为一名学生获得了最大的乐趣,除了我曾经和一些来自 RSC 的人一起参加莎士比亚研讨会。

【问题讨论】:

  • 欢迎来到 Stack Overflow。请尽快阅读FAQvread() 函数不是 C99(或 POSIX)的一部分。您可以在 POSIX 网站上找到有关 vscanf() 的信息。返回值与任何其他scanf() 系列函数相同;成功转换分配的数量。
  • 哦,好吧,所以它就像 sscanf...谢谢你的链接,但有什么办法可以让我把它简化一下吗?我假设你的意思是一样的,“除了不使用可变数量的参数调用它们,而是使用 标头中定义的参数列表调用它们。”
  • 如果您首先不知道如何使用可变长度参数列表,那么您不太可能尝试使用vfscanf()。在不到 30 年的 C 编程生涯中,我从未需要它。我知道如何使用它,但我从来没有处于这样做有意义的位置;事实上,我不确定我能否设计出一个有意义的场景。 (顺便说一句,vread() 对 Google 来说是未知的。)你知道如何使用 vfprintf() 吗?你知道如何使用fscanf()吗?将这两个知识综合到使用vscanf() et al 中基本上是直截了当的。
  • 我知道 fscanf(),是的,先生。 vread() 显然只是 IBM 的家伙/gals 用来干净地实现 vscanf 的函数,现在我了解他们是如何使用它的,它实际上非常令人着迷。我将查找 vfprintf 以帮助我理解它。如果这是一个愚蠢的询问,我深表歉意。
  • IBM URL 处代码中的vread() 函数只是一个说明函数;展示使用vscanf()的一种方式的车辆。该代码演示了其中一个问题;您必须以某种方式知道应该转换多少个值才能知道是否存在错误。示例 main() 函数知道它传递了一种转换 4 个值和 4 个适当指针的格式,因此它能够通过 vread() 检查来自 vscanf() 的返回。与直接调用scanf() 相比,示例代码没有任何好处,但它显示了需要的机制。

标签: c input standards c99 c11


【解决方案1】:

vscanf 类似于 scanf,而不是 sscanf 或 fscanf。它与 scanf 的不同之处在于 scanf 采用可变数量的参数,而 vscanf 采用 va_list 参数作为指向可变参数列表的指针。 vscanf 的使用很少;它主要是为了完整性(使用 vprintf 更常见)。使用 vscanf 的一个可能示例是,如果您有大量具有不同参数的 scanf 调用,并且每次它都会采取一些错误操作 - 相同的错误操作 - 如果 scanf 无法读取其所有参数。然后你可以编写一个 scanf_and_check_for_error 函数,它像 scanf 一样接受可变参数,添加一个 count 参数,它是 scanf 的预期返回值,将参数列表传递给 vscanf,检查它的返回值并在以下情况下采取错误操作返回值是错误的。例如,

void scanf_and_check(int count, char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    int rc = vscanf(fmt, ap);
    if (rc != count)
    {
        ErrorMessageBox("Bad input. This program employs a radical form of the fail-fast principle ... exiting!");
        exit(1);
    }
    va_end(ap);
}

【讨论】:

  • 这是一个很好的答案,谢谢。绝对有助于我理解 vscanf()
  • 如何在 if 子句中递归调用 scanf_and_check ?
【解决方案2】:

虽然没有太大帮助,但我怀疑您可能尝试了错误的工具来完成这项工作。 vscanf 旨在在开发 scanf 系列的“前端”时使用,并且是一个非常“低级”的工具。

您可能想使用 fscanf。如果您真的想使用 vscanf 逻辑(及其所有 va_list 丑陋),请查看 vfscanf(在您的示例中链接)

【讨论】:

  • 完全没有帮助,先生...就像我说的,我基本上什么都不知道。这实际上是一个非常有用的信息。它帮助我理解了 vscanf 是什么,尽管很明显现在我应该坚持使用 fgets() 和 sscanf() 或者只使用 fscanf()...我什至可以使用 fgetc()。
猜你喜欢
  • 1970-01-01
  • 2021-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-18
  • 1970-01-01
  • 2015-03-30
  • 1970-01-01
相关资源
最近更新 更多