免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 7530 | 回复: 12
打印 上一主题 下一主题

[C] 怎样实现asprintf类似的功能? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-12-26 16:55 |只看该作者 |倒序浏览
15可用积分
在开发中,经常要蛋疼的format字符串,以前以为用snprintf可以减轻蛋疼,
但snprintf还得自己malloc一块内存,直到用了asprintf之后才一劳永逸,
asprintf真是谁用谁知道,就一个爽字!

最近开发中要实现asprintf类似的功能,基本的思路还是知道:
1>.必须使用可变参数列表;
2>.要对格式字符串进行扫瞄,要知道参数的类型.

我查看了glibc中asprintf的实现,发现调用了vasprintf,
而vasprintf内部相当复杂,是用流和文件实现的。
我不知它是怎么扫瞄参数列表的,最关键地是判断参数类型,
因为可变参数列表是没办法直接获得参数类型的。

本人才学疏浅,没看懂vasprintf的实现,所以请教广大坛友,
在此先多谢了!

最佳答案

查看完整内容

回复 8# osmanthusgfy 哦……那不是直接类似 printf 就行了,一样是可变参数列表,囧。获得参数类型是自己分析字符串的,大意是这样的:

论坛徽章:
0
2 [报告]
发表于 2012-12-26 16:55 |只看该作者
回复 8# osmanthusgfy

哦……那不是直接类似 printf 就行了,一样是可变参数列表,囧。

获得参数类型是自己分析字符串的,大意是这样的:
  1. int printf(char const *format, ...)
  2. {
  3.     va_start(ap, format);

  4.     从头至尾遍历 format 分析获得每个类型标识符(%?),然后根据标识符取参数,比如:
  5.         如果是 d: 用 va_arg(ap, int) 获取该参数
  6.         如果是 s: 用 va_arg(ap, char *) 获取该参数

  7.     va_end(ap);
  8. }
复制代码

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
3 [报告]
发表于 2012-12-26 17:06 |只看该作者
根据格式化串“判断”参数个数及类型

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
4 [报告]
发表于 2012-12-26 17:11 |只看该作者
BTW,为什么不定义一个字符串数组而非得malloc呢?难道长度很长而且不好确定?那性能也会有问题。
用了asprintf还得free吧

论坛徽章:
0
5 [报告]
发表于 2012-12-26 17:24 |只看该作者
回复 3# hellioncu

参数的大小不固定,我们不能假设buf的最大尺寸.


   

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
6 [报告]
发表于 2012-12-26 17:27 |只看该作者
osmanthusgfy 发表于 2012-12-26 17:24
回复 3# hellioncu

参数的大小不固定,我们不能假设buf的最大尺寸.


我总觉得这样拼起来的不会很长,大不了给个几十K内存。

如果这样都不够,我觉得设计上有问题了

论坛徽章:
0
7 [报告]
发表于 2012-12-26 17:35 |只看该作者
vsnprintf 调用成功时的返回值就是完整输出时所需大小,所以……不用自己去解析,直接用这个返回值 malloc 就行了……
  1. #include <stdarg.h>

  2. int asprintf(char **ret, const char *format, ...)
  3. {
  4.     va_list ap;

  5.     *ret = NULL;

  6.     va_start(ap, format);
  7.     int count = vsnprintf(NULL, 0, format, ap);
  8.     va_end(ap);

  9.     if (count >= 0)
  10.     {
  11.         char* buffer = malloc(count + 1);
  12.         if (buffer == NULL)
  13.             return -1;

  14.         va_start(ap, format);
  15.         count = vsnprintf(buffer, count + 1, format, ap);
  16.         va_end(ap);

  17.         if (count < 0)
  18.             free(buffer);
  19.         else
  20.             *ret = buffer;
  21.     }

  22.     return count;
  23. }
复制代码

论坛徽章:
0
8 [报告]
发表于 2012-12-26 17:35 |只看该作者
hellioncu 发表于 2012-12-26 17:27
我总觉得这样拼起来的不会很长,大不了给个几十K内存。

如果这样都不够,我觉得设计上有问题了


我们暂时先不讨论动态分配内存的问题,因为这明显没意义。

请帮忙解答问题,多谢!

论坛徽章:
0
9 [报告]
发表于 2012-12-26 17:39 |只看该作者
timothyqiu 发表于 2012-12-26 17:35
vsnprintf 调用成功时的返回值就是完整输出时所需大小,所以……不用自己去解析,直接用这个返回值 malloc  ...


可能是我没有说清楚,
我的需求是要通过可变参数列表获得所有的参数,以及每个参数的类型。
获得之后不是格式化字符串,要实现自己的逻辑.

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
10 [报告]
发表于 2012-12-26 20:44 |只看该作者
osmanthusgfy 发表于 2012-12-26 17:35
我们暂时先不讨论动态分配内存的问题,因为这明显没意义。

请帮忙解答问题,多谢!


我在2楼不是已经回答了么
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP