[C语言] C语言中如何传递可变参数

[复制链接]
 楼主| wuyansky 发表于 2013-10-31 13:31 | 显示全部楼层 |阅读模式
各位大神,我在自己的一个函数里面调用了库函数sprintf(),但是不知道怎样把可变参数传递给它。
程序如下,不能通过编译。

void LCD12864_Printf(unsigned char X, unsigned char Y, const char *FORMAT, ...)
{            
   char str[17]="\0";     
   sprintf(str, FORMAT, ...);   
   LCD12864_PositionString(X,Y,str);   //在屏幕上坐标为(X,Y)处显示str
}

请教大神,如何将可变参数...原样传给sprintf()?
谢谢!
ayb_ice 发表于 2013-10-31 13:36 | 显示全部楼层
这个找个KEIL例程看一下就知道了
lhchen922 发表于 2013-10-31 14:31 | 显示全部楼层
linux的源代码里面找。。。
laoxu 发表于 2013-10-31 14:39 | 显示全部楼层
用指针~~~
laoxu 发表于 2013-10-31 14:45 | 显示全部楼层
char a[ ]="1234567890";
char *p;
p = a;

void LCD12864_Printf(unsigned char X, unsigned char Y, const char *FORMAT,unsigned char *p)
{            
   char str[17]="\0";     
   sprintf(str, FORMAT, ...);   
   LCD12864_PositionString(X,Y,str);   //在屏幕上坐标为(X,Y)处显示str
}
ayb_ice 发表于 2013-10-31 14:50 | 显示全部楼层
RT:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| wuyansky 发表于 2013-10-31 17:46 | 显示全部楼层
ayb_ice 发表于 2013-10-31 13:36
这个找个KEIL例程看一下就知道了

请大人明示...
 楼主| wuyansky 发表于 2013-10-31 17:47 | 显示全部楼层
lhchen922 发表于 2013-10-31 14:31
linux的源代码里面找。。。

小弟还未到这一境界啊!
lhchen922 发表于 2013-10-31 18:02 | 显示全部楼层
国内 RT-THREAD里面 也有。。不过感觉还是从linux来的。
 楼主| wuyansky 发表于 2013-10-31 19:05 | 显示全部楼层
laoxu 发表于 2013-10-31 14:45
char a[ ]="1234567890";
char *p;
p = a;

不对吧大哥?
*p那个参数都没用。。。
laoxu 发表于 2013-10-31 19:26 | 显示全部楼层
wuyansky 发表于 2013-10-31 19:05
不对吧大哥?
*p那个参数都没用。。。

把p指针指向的数据, 加到 sprintf()函数中输出, 就用上了... :lol
micropower 发表于 2013-10-31 21:00 | 显示全部楼层
wuyansky 发表于 2013-10-31 19:05
不对吧大哥?
*p那个参数都没用。。。

看来你还没学到指针呢。
黄小俊 发表于 2013-10-31 21:01 | 显示全部楼层
jiemnij 发表于 2013-11-1 09:41 | 显示全部楼层
从你的代码中可以看出.你想使用sprintf打印功能..
你这种方式是实现不了  在你的函数内部调用sprintf功能的.
除非sprintf有linux累死的 vsprintf版本
vsprintf 原型
int vsprintf(char *string, char *format, va_list param);
最好的办法是.你自己实现一个vsprintf功能..或者干脆自己写一个LCD12864_Printf 格式化版本
嵌入式用.一般都不能用到所有sprintf里面的功能.自己实现其中的一部分就好了.
而且.占用堆栈,代码空间还小,

好人做到底.....给你个我早期写的串口命令行, 适当的自己修改一下吧...............
void uart_printf(const char *src,...)
{
        unsigned int tmp;
        va_list lst;
        va_start(lst, src);
        while(*src) {
                if (*src != '%'){
                        uart_push(*src);
                }
                else {
                        switch (*++src) {
                                case 'c':        uart_push(va_arg(lst, char));                break;
                                case 'd':        dec_to_str(va_arg(lst, int), 0);        break;
                                case 'u':        dec_to_str(va_arg(lst, int), 1);        break;
                                case 's':        push_str(va_arg(lst, char*));                break;
                                case 'x':        push_word_hex(va_arg(lst, int));        break;
                                case 'X':
                                        tmp = va_arg(lst, unsigned char);
                                        uart_push(tab[tmp>>4& 0xf]);
                                        uart_push(tab[tmp        & 0xf]);
                                        break;
                                case 'l':
                                        push_word_hex(va_arg(lst, int));
                                        push_word_hex(va_arg(lst, int));
                                        break;
                                case 'b':
                                        tmp = va_arg(lst,char);
                                        push_str(bin_tab[tmp>>4]);
                                        uart_push('_');
                                        push_str(bin_tab[tmp&15]);
                                        break;
                                case 'B':
                                        tmp = va_arg(lst, int);
                                        push_str(bin_tab[tmp>>12]);
                                        uart_push('_');
                                        push_str(bin_tab[tmp>>8&15]);
                                        uart_push('_');
                                        push_str(bin_tab[tmp>>4&15]);
                                        uart_push('_');
                                        push_str(bin_tab[tmp&15]);
                                        break;
                                default:
                                        uart_push(*src);
                                        break;
                        }
                }
                src++;
        }
        uart_send();
}
mohanwei 发表于 2013-11-1 11:16 | 显示全部楼层
太复杂了,直接用printf就行了……然后自己写一个底层驱动putchar()以替代编译器提供的那个,在putchar里你可以把字符弄到液晶、LED、串口……
msblast 发表于 2013-11-1 11:50 | 显示全部楼层
mohanwei 发表于 2013-11-1 11:16
太复杂了,直接用printf就行了……然后自己写一个底层驱动putchar()以替代编译器提供的那个,在putchar里你 ...

这哥们说的是输出重定向,这是另外一种解决问题思路。
原野之狼 发表于 2013-11-1 12:32 | 显示全部楼层
跟linux还是windows没有关系,这个是c标准。

使用   va_list  va_start  va_end
使用   vsprintf

剩下的就靠你自己了
outstanding 发表于 2013-11-1 12:47 | 显示全部楼层
:lol  其实实现方式很多啊。用指针指向数组也可以
msblast 发表于 2013-11-1 13:00 | 显示全部楼层
原野之狼 发表于 2013-11-1 12:32
跟linux还是windows没有关系,这个是c标准。

使用   va_list  va_start  va_end

根据你的提示,写了个例子
#include <stdarg.h>
#include <stdio.h>

void log_printf(char*fmt,...) {
    char tmp[128];
    va_list args;
    va_start(args, fmt);
    vsprintf(tmp,fmt,args);
    printf(tmp);
    va_end(args);
}

void main(void) {
    char *s1 = "asfdwedfsasdfsdf";
    log_printf("%d %d\n", 1, 2);
    log_printf("%s\n", s1);
}

评分

参与人数 1威望 +4 收起 理由
原野之狼 + 4 赞一个!

查看全部评分

jiemnij 发表于 2013-11-1 14:01 | 显示全部楼层
本帖最后由 jiemnij 于 2013-11-1 14:04 编辑

汗....一直以为vsprintf是linux用.....
原来本身就是属于c标准的.......
void LCD12864_Printf(unsigned char X, unsigned char Y, const char *FORMAT, ...)
{            
   char str[17]="\0";     
    va_list args;
    va_start(args, fmt);
    vsprintf(str, FORMAT, args);
    va_end(args);
   LCD12864_PositionString(X,Y,str);   //在屏幕上坐标为(X,Y)处显示str
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

84

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部