如何在C中编写自己的printf()?

实际上我正在尝试使用varags在C中编写自己的printf()。但我没有得到正确的解决方案。谁能帮我吗?

已邀请:

wrerum

赞同来自:

如果你有时间而且非常好奇,你可以学习GNU libc的版本: 请参阅printf,后者又使用vprintf,它使用vfprintf

walias

赞同来自:

Linux va_start(3)手册页提供了编写此类函数的非常好的示例(更简单但通常所有主要的砖都在那里)。您还可以检查几乎所有libstdc实现。

gnihil

赞同来自:

至少有两本书可以很好地解释如何编写类似printf()的格式化函数(以及完整的工作示例):

taut

赞同来自:

This answer may help you了解如何编写可变参数函数。注意,没有进行错误/边界检查,没有设置任何属性来告诉编译器哪种参数可能是合适的,没有实现仅使用printf()的好处。 它可能是也可能不是您正在寻找的示例。 相关的片段(在这里扩展了一下):

#include <stdarg.h>
void _printf(FILE *out, va_list ap)
{
    vfprintf(out, fmt, ap);
}
void printf(const char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    _printf(stdout, ap);
    va_end(ap);
}
注意:使这些返回正确的类型(有符号整数)留给读者练习。这看起来很像我的家庭作业,我只是想让你超越使用va_start和va_end的任何关键点,并且显示可以将va_list传递给辅助函数以避免在如此多的几乎相同的实现中复制代码事情。 我强烈建议查看BSD(甚至glibc)printf子系统实现。你也可以看看uclibc,dietlibc等。

weos

赞同来自:

在实现printf()函数之前,我们必须处理异常问题,即可变参数。我们知道printf除了字符串之外还可以使用很多参数。       所以我们必须使用一个名为stdarg.h的标准库来处理这个变量参数问题。在这个实现上下文中,我们不需要学习整个stdarg.h库,因为我们使用这些库的一些宏函数,这是我们的C程序可以直接理解的。 Here is the code source which explain nice and fast

#include<stdio.h> 
#include<stdarg.h>
void Myprintf(char *,...);              //Our printf function
char* convert(unsigned int, int);       //Convert integer number into octal, hex, etc.
int main() 
{ 
    Myprintf(" WWW.FIRMCODES.COM \n %d", 9);
return 0;
}
void Myprintf(char* format,...) 
{ 
    char *traverse; 
    unsigned int i; 
    char *s;
//Module 1: Initializing Myprintf's arguments 
    va_list arg; 
    va_start(arg, format);
for(traverse = format; *traverse != '\0'; traverse++) 
    { 
        while( *traverse != '%' ) 
        { 
            putchar(*traverse);
            traverse++; 
        }
traverse++;
//Module 2: Fetching and executing arguments
        switch(*traverse) 
        { 
            case 'c' : i = va_arg(arg,int);     //Fetch char argument
                        putchar(i);
                        break;
case 'd' : i = va_arg(arg,int);         //Fetch Decimal/Integer argument
                        if(i<0) 
                        { 
                            i = -i;
                            putchar('-'); 
                        } 
                        puts(convert(i,10));
                        break;
case 'o': i = va_arg(arg,unsigned int); //Fetch Octal representation
                        puts(convert(i,8));
                        break;
case 's': s = va_arg(arg,char *);       //Fetch string
                        puts(s); 
                        break;
case 'x': i = va_arg(arg,unsigned int); //Fetch Hexadecimal representation
                        puts(convert(i,16));
                        break; 
        }   
    }
//Module 3: Closing argument list to necessary clean-up
    va_end(arg); 
}
char *convert(unsigned int num, int base) 
{ 
    static char Representation[]= "0123456789ABCDEF";
    static char buffer[50]; 
    char *ptr;
ptr = &buffer[49]; 
    *ptr = '\0';
do 
    { 
        *--ptr = Representation[num%base]; 
        num /= base; 
    }while(num != 0);
return(ptr); 
}

要回复问题请先登录注册