变长参数

标准头文件<stdarg.h>包含一组宏定义, 它们对如何遍历参数表进行了定义.

va_list ap; //参数指针

va_startap初始化为指向第一个无名参数的指针,使用ap之前,va_start必须被调用一次.参数表至少包含一个有名参数,va_start将最后一个有名参数作为起点.

每次调用va_arg,该函数都返回一个参数, 并将ap 指向下一个参数.
va_arg使用一个类型名来决定返回的对象类型, 指针移动的步长.

必须在函数返回之前调用va_end完成一些清理工作.

minprintf

#include <stdio.h>
#include <stdarg.h>

/* minprintf: minimal printf with variable argument list */
void minprintf (char *fmt, ...)
{
    va_list ap;     /* points to each unnamed arg in turn */
    char *p, *sval;
    int ival;
    double dval;

    va_start(ap, fmt);      /* make ap point to 1st unnamed arg */
    for (p = fmt; *p; p++){
        if (*p != '%') {
            putchar (*p);
            continue;
        }
        switch (*++p) {
            case 'd':
                ival = va_arg(ap, int);
                printf("%d", ival);
                break;
            case 'f':
                dval = va_arg(ap, double);
                printf("%f", dval);
                break;
            case 's':
                for (sval = va_arg(ap, char *); *sval; sval++)
                    putchar(*sval);
                    break;
            default:
                putchar(*p);
                break;
        }
    }
    va_end(ap);     /* clean up when done */
}

int main ()
{
    minprintf ("%d %s %f\n", 123, "today", 12);
    return 0;
}

minscanf

scanf 函数忽略格式串中的空格和制表符.
注意,scanf 和 sscanf 函数的所有参数都必须是指针.
从string中读取.

int sscanf(char *string, char *format, arg1, arg2, ...)
#include <stdio.h>
#include <stdarg.h>

int minscanf (char *fmt, ...)
{
    va_list ap;
    int n, *ival;
    double *dval;
    char c, *p, *sval;

    n = 0;
    va_start(ap, fmt);
    for (p = fmt; *p; p++){
        if (*p != '%'){
            c = getchar();
            //if (c == '\n')
            //  c = getchar();
            if(*p == c)
                continue;
            else {
                break;
                return n;
            }
        }
        switch (*++p) {
            case 'd':
                ival = va_arg(ap, int *);
                if (scanf("%d", ival))
                    n++;
                else 
                    return n;
                break;
            case 's':
                sval = va_arg(ap, char *);
                if (scanf("%s", sval))
                    n++;
                else
                    return n;
                break;
            case 'l':
                if (*++p == 'f'){
                    dval = va_arg(ap, double *);
                    if (scanf("%lf", dval))
                        n++;
                    else
                        return n;
                }
            default:
                return n;
        }
    }
    va_end(ap);
    return n;
}

int main ()
{
    int i;
    char s[20];
    double d;
    int n = minscanf("%d/%s %lf", &i, s, &d);
    printf("%d %s %.f\t%d\n", i, s, d, n);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值