C 可变参数函数:如何指定给 va_arg 的类型

2024-04-30

在像 printf 这样的函数中,我们使用stdarg.h处理可变参数。

void print(int args,...){
    va_list ap;
    va_start(ap, args);
    int i = 0;
    for(i=0; i<args; i++){
        printf("%d\n",va_arg(ap, int));
    }
    va_end(ap);
}

我们想要解析格式列表(赋予我们的可变参数函数的第一个参数)以跟踪格式列表中指定的参数类型,然后使用适当的类型调用 va_arg 。

我进行第一个循环来解析格式列表,将说明符字母存储到数组中。 所以我知道我们期望哪种类型以及有多少种。

ex: ft_like_printf("Watch your %d %s\n", 6, "Spider pig");

specifiers_list = "ds"所以 d int 和 s char* (与 printf 相同的说明符)

但如何编码呢动态地?使用不同类型调用 va_arg 的语法是什么?

我读过了THIS https://stackoverflow.com/a/5551632/3206885 and THAT https://stackoverflow.com/a/1722238/3206885我认为这就是我正在寻找的,不是吗? 如果是,该怎么办?包含枚举+联合的结构或包含联合+函数指针的结构的真实情况是什么?

为了处理不同的数据类型,我从以下开始:

typedef struct s_flist
{
    char c;
    (*f)();
}              t_flist;

t_flist flist[] = 
    {
        { 's',  &putstr  },
        { 'i',  &put_number },
        { 'd',  &put_number }
    };

类型在 C 中不是一等公民。

但您需要关心的类型并不多:您可以安全地从unsigned to signed反之亦然char* and void*,所以对于一个基本的 printf,你必须处理:

  • char
  • short
  • int
  • long
  • float
  • double
  • void*

union来救援!

typedef union
{
    char as_char;
    short as_short;
    int as_int;
    long as_long;
    float as_float;
    double as_double;
    void* as_ptr;
} t_value;

typedef enum {
    CHAR_T,
    INT_T,
    /* It goes on */
    ...
} t_type;

t_value get_value(va_list ap, t_type type) {
    /* You can't avoid this step, there is no way to iterate over types */
    switch (type) {
        case T_CHAR:
            return va_arg(ap, char);
        case T_INT:
            /* ... */
    }
}

然后你只需要创建一个查找表,存储函数指针和t_type对于每个有效的格式说明符。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C 可变参数函数:如何指定给 va_arg 的类型 的相关文章

  • 如何在MVVM中管理多个窗口

    我知道有几个与此类似的问题 但我还没有找到明确的答案 我正在尝试深入研究 MVVM 并尽可能保持纯粹 但不确定如何在坚持模式的同时启动 关闭窗口 我最初的想法是向 ViewModel 发送数据绑定命令 触发代码来启动一个新视图 然后通过 X
  • 获取按下的按钮的返回值

    我有一个在特定事件中弹出的表单 它从数组中提取按钮并将标签值设置为特定值 因此 如果您要按下或单击此按钮 该函数应返回标签值 我怎样才能做到这一点 我如何知道点击了哪个按钮 此时代码返回 DialogResult 但我想从函数返回 Tag
  • 将数组向左或向右旋转一定数量的位置,复杂度为 o(n)

    我想编写一个程序 根据用户的输入 正 gt 负 include
  • UML类图:抽象方法和属性是这样写的吗?

    当我第一次为一个小型 C 项目创建 uml 类图时 我在属性方面遇到了一些麻烦 最后我只是将属性添加为变量 lt
  • 如何忽略“有符号和无符号整数表达式之间的比较”?

    谁能告诉我必须使用哪个标志才能使 gcc 忽略 有符号和无符号整数表达式之间的比较 警告消息 gcc Wno sign compare 但你确实应该修复它警告你的比较
  • 使闭包捕获的变量变得易失性

    闭包捕获的变量如何与不同线程交互 在下面的示例代码中 我想将totalEvents 声明为易失性的 但C 不允许这样做 是的 我知道这是错误的代码 这只是一个例子 private void WaitFor10Events volatile
  • 在 Visual Studio 2008 上设置预调试事件

    我想在 Visual Studio 中开始调试程序之前运行一个任务 我每次调试程序时都需要运行此任务 因此构建后事件还不够好 我查看了设置的 调试 选项卡 但没有这样的选项 有什么办法可以做到这一点吗 你唯一可以尝试的 IMO 就是尝试Co
  • 获取没有非标准端口的原始 url (C#)

    第一个问题 环境 MVC C AppHarbor Problem 我正在调用 openid 提供商 并根据域生成绝对回调 url 在我的本地机器上 如果我点击的话 效果很好http localhost 12345 login Request
  • Web API - 访问 DbContext 类中的 HttpContext

    在我的 C Web API 应用程序中 我添加了CreatedDate and CreatedBy所有表中的列 现在 每当在任何表中添加新记录时 我想填充这些列 为此目的我已经覆盖SaveChanges and SaveChangesAsy
  • 指针减法混乱

    当我们从另一个指针中减去一个指针时 差值不等于它们相距多少字节 而是等于它们相距多少个整数 如果指向整数 为什么这样 这个想法是你指向内存块 06 07 08 09 10 11 mem 18 24 17 53 7 14 data 如果你有i
  • 如何将图像路径保存到Live Tile的WP8本地文件夹

    我正在更新我的 Windows Phone 应用程序以使用新的 WP8 文件存储 API 本地文件夹 而不是 WP7 API 隔离存储文件 旧的工作方法 这是我如何成功地将图像保存到 共享 ShellContent文件夹使用隔离存储文件方法
  • 当操作繁忙时,表单不执行任何操作(冻结)

    我有一个使用 C 的 WinForms 应用程序 我尝试从文件中读取一些数据并将其插入数据表中 当此操作很忙时 我的表单冻结并且无法移动它 有谁知道我该如何解决这个问题 这可能是因为您在 UI 线程上执行了操作 将文件和数据库操作移至另一个
  • 实体框架 4 DB 优先依赖注入?

    我更喜欢创建自己的数据库 设置索引 唯一约束等 使用 edmx 实体框架设计器 从数据库生成域模型是轻而易举的事 现在我有兴趣使用依赖注入来设置一些存储库 我查看了 StackOverflow 上的一些文章和帖子 似乎重点关注代码优先方法
  • 将 xml 反序列化为类,list<> 出现问题

    我有以下 XML
  • WCF:将随机数添加到 UsernameToken

    我正在尝试连接到用 Java 编写的 Web 服务 但有些东西我无法弄清楚 使用 WCF 和 customBinding 几乎一切似乎都很好 除了 SOAP 消息的一部分 因为它缺少 Nonce 和 Created 部分节点 显然我错过了一
  • const、span 和迭代器的问题

    我尝试编写一个按索引迭代容器的迭代器 AIt and a const It两者都允许更改容器的内容 AConst it and a const Const it两者都禁止更改容器的内容 之后 我尝试写一个span
  • Validation.ErrorTemplate 的 Wpf 动态资源查找

    在我的 App xaml 中 我定义了一个资源Validation ErrorTemplate 这取决于动态BorderBrush资源 我打算定义独特的BorderBrush在我拥有的每个窗口以及窗口内的不同块内
  • C 中的异或运算符

    在进行按位操作时 我在确定何时使用 XOR 运算符时遇到一些困难 按位与和或非常简单 当您想要屏蔽位时 请使用按位 AND 常见用例是 IP 寻址和子网掩码 当您想要打开位时 请使用包含或 然而 XOR 总是让我明白 我觉得如果在面试中被问
  • 如何在 C++ BOOST 中像图形一样加载 TIFF 图像

    我想要加载一个 tiff 图像 带有带有浮点值的像素的 GEOTIFF 例如 boost C 中的图形 我是 C 的新手 我的目标是使用从源 A 到目标 B 的双向 Dijkstra 来获得更高的性能 Boost GIL load tiif
  • 恢复上传文件控制

    我确实阅读了以下帖子 C 暂停 恢复上传 https stackoverflow com questions 1048330 pause resume upload in c 使用 HTTP 恢复上传 https stackoverflow

随机推荐

  • Joda Time 持续时间或间隔中的分钟数

    我有这个简单的代码 DateTime date new DateTime dateValue DateTime currentDate new DateTime System currentTimeMillis System out pri
  • 在Vim中,如何删除单词的后缀?

    在vim中 在正常模式下 如果光标位于单词中 而不是最后一个字母 de从光标位置删除单词的后缀 如果光标位于最后一个字母上 x也这样做 同时de会跳到下一个单词的末尾 您将使用什么命令在这两种情况下都有效 无论最后一个字母与否 目的是将命令
  • 如何设置带有选项卡的多个滑动视图的默认选项卡?

    我真的被困住了 我在主要活动中使用选项卡进行了四个滑动视图 但我想要的是当用户打开应用程序时 它会自动显示第二个选项卡而不是第一个选项卡 这是我的 MainActivity java public class MainActivity ex
  • Three.js 光线投射器可以与组相交吗?

    我想知道我的光线投射器是否正在查看我已加载的 OBJ 由于从 Cinema4D 导出的方式 我相信 OBJ 是一个具有 3 个子级的 THREE Group 而不是 THREE Object 我可以更改我的 raycaster 代码行来查找
  • 发送同一条短信两次

    我正在尝试制作一个短信Android应用程序 但我收到了一个我以前从未见过的错误 即使在谷歌中我也没有找到类似的东西 所以 如果你能帮助我 我会很高兴 由于某种原因 程序同时发送两条消息 同一条短信 但这只是发生在生产中 当我使用模拟器时
  • Android Studio 无法下载并附加某些库的源代码

    就我而言 是这样的源代码是这样的 https i stack imgur com Xuo0X png 然后 我单击 下载源 但看到此错误 error https i stack imgur com 26R68 png java util N
  • 当 max-height 固定时 CSS 自动列计数

    我希望实现一个布局 其中一个元素 在我的例子中是一个 ul 当高度达到一定限制时扩展到 2 或更多 列 例如 如果高度仅够容纳 3 个项目 而我有 5 个项目 则第 4 和第 5 个项目将转到第二列 该列仅在需要时创建 我尝试通过设置来做到
  • VS Code Python autopep8 不支持 2 个空格悬挂缩进

    我正在尝试让 autopep8 正常工作 以 2 个空格而不是 4 个空格正确缩进 Python 代码 我正在使用带有 Python 扩展的 VS Code 该扩展使用 autopep8 进行格式化 我发现here https stacko
  • 如何在 Laravel 中基于迁移文件制作模型

    我已经创建了一个迁移 我想根据迁移文件制作一个模型 这可能吗 如果是这样 该怎么办 这是不可能的 到目前为止 您最多可以通过运行以下命令同时创建迁移和模型 php artisan make model ModelName m
  • Python 3D 插值加速

    我有以下用于插入 3D 体积数据的代码 Y X Z np shape volume xs np arange 0 X ys np arange 0 Y zs np arange 0 Z points list zip np ravel re
  • PHP 警告:在 php 7.3 中使用 password_hash() 时使用未定义的常量 PASSWORD_ARGON2ID

    我最近通过 Plesk 的 Web GUI 安装了 PHP 7 3 6 用于 Web 应用程序的开发副本 因为我打算将生产环境从 php 7 0 更新到 7 3 我决定借此机会将密码哈希从 PBKDF2 升级到 Argon2ID 因为 PH
  • Swift 3 / Xcode 8 升级 - 工作副本错误导致 100 个 DerivedData 文件丢失

    我刚刚升级到 XCode 和 Swift 的最新 Beta 版本 但使用转换器后 我的应用程序项目现在有超过 200 个构建时黄色错误 所有错误均指出 projectDirectoy DerivedData XXXXXXXXX XXXX X
  • 在 Android 中像画廊图像一样用手指展开图像视图缩放

    我想像画廊图像一样缩放图像 我们可以通过手指展开和缩小来放大和缩小图像 怎么做 任何机构都可以帮忙吗 感谢和问候 您本质上要求的是图像的多点触控缩放 对吗 如果是这样 这应该是您正在寻找的答案 如何获得图像的缩放功能 https stack
  • 更改 ggsurvplot 的 x 轴标签

    library survival library survminer 我正在使用 survminer 包来绘制未经调整的 Kaplan Meier 图 我正在计算比较不同暴露的死亡率 我有一个非常具体的问题 有没有办法改变ggsurvplo
  • 使用 HTML / CSS / JavaScript 隐藏 YouTube 视频控件(标题、稍后观看、分享)

    我正在我的网站中嵌入 Youtube 每日动态视频 我不希望 Youtube 视频控件在我的网站上可见 请查看附件 我想删除顶部的控件 以红色突出显示 并且还想删除底部的控件 以红色突出显示 以前可以在 YouTube 视频中使用 show
  • 如何将 SVG 元素下载为 SVG 文件

    在过去的几个月里 我一直在编写处理椭球地球的代码 最近我已经完成了它 我的教授现在希望我将我制作的图表的图片作为 SVG 文件发送给他 我知道在Python中你可以在你的项目中放入几行代码来让它下载图像 但我不确定它是如何工作的JavaSc
  • Rails 3.2.2 mysql2 适配器错误

    我在让 mysql2 适配器与最新版本的 Rails 一起工作时遇到了麻烦 我刚刚生成了一个新项目 将以下内容添加到我的 gemfile 中 gem mysql2 lt 0 3 7 然后当然跑了 bundle install 我还修改了我的
  • 如何防止 iOS 独立 Web 应用程序锁定设备?

    我的原型设计服务创建独立的 不可安装的 iOS Web 应用程序 有时他们会在使用时锁定设备 主页按钮停止工作 应用程序继续工作 以下内容在设备的控制台中重复显示 通过附加到 xcode 检索 Apr 25 14 34 57 SpringB
  • Delphi 2009之前如何处理UTF-8和ANSI转换?

    在 Delphi 2009 中 我们有 RichEdit1 Lines LoadFromFile OpenDialog1 FileName TEncoding UTF8 RichEdit1 Lines SaveToFile OpenDial
  • C 可变参数函数:如何指定给 va_arg 的类型

    在像 printf 这样的函数中 我们使用stdarg h处理可变参数 void print int args va list ap va start ap args int i 0 for i 0 i