简体   繁体   English

使用va_start,va_end va_arg和syscalls的printf实现

[英]printf implementation using va_start , va_end va_arg and syscalls

Could anybody show me how my implementation of printf or scanf using va_start , va_end , va_arg and syscalls read/write should look? 有人可以告诉我使用va_startva_endva_arg和syscall读/写的printfscanf实现如何吗?

I have something like this: 我有这样的事情:

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

char *translate(unsigned int, int);

void myprintf(char * frmt,...){
    char *pointer;
    int iterator;
    char *s;
    va_list argp;
    va_start(argp, frmt);
    pointer=frmt;

    for(pointer=frmt; *pointer!='\0';pointer++){
        if(*pointer!='%'){
            putchar(*pointer);
            continue;
        }
        pointer++;

        switch(*pointer){       
        case 'd':
            iterator=va_arg(argp,int);
            if(iterator<0){
                iterator=-iterator;
                putchar('-');
            }
            puts(translate(iterator,10));
            break;
        case 's':
            s=va_arg(argp,char *);
            puts(s);
            break;
        //case 'b': b=va_arg(argp, );;break;
        case 'x':
            unsigned=va_arg(argp, unsigned int);
            puts(translate(unsigned,16));
            break;
        case '%':
            putchar('%');
            break;
        }
    }
    va_end(argp);   
}

char *translate(unsigned int num, int base){
    static char buff[33];
    char *ptr;
    ptr=&buff[sizeof(buff)-1];
    *ptr='\0';
    do{
        *--ptr="0123456789abcdef"[num%base];
        num/=base;
    } while(num!=0);

    return(ptr);
}

void main(){
    void myprintf(char *,...);
    char *translate(unsigned int, int);
    int iterator=65;
    char str[]="przyklad";
    myprintf("\njbleble%s%d%x",str,iterator,iterator);
}

How can I eliminate putchar and use read/write? 如何消除putchar并使用读/写?

Here's the easy way to do this: 这是执行此操作的简单方法:

#define FD_STDOUT 1
void putchar(int c) {
    char ch = c;
    write(FD_STDOUT, &ch, 1);
}

This will write out the given character to stdout, without using the C standard library's IO functions. 这会将给定的字符写到stdout,而无需使用C标准库的IO函数。 Don't mix this with the C standard library's IO functions, however, as this probably won't work. 但是,请勿将其与C标准库的IO函数混合使用,因为这可能行不通。

As I said, this is somewhat naive: this solution will work, but you should think about the following cases for a robust solution: 就像我说的那样,这有点天真:此解决方案可以工作,但是您应该考虑以下情况,以获得可靠的解决方案:

  • What if the syscall returns early (with a return value of zero)? 如果系统调用提前返回(返回值为零)怎么办? This can happen when a signal is received. 收到信号时可能会发生这种情况。
  • What if the write syscall fails? 如果write系统调用失败怎么办? You should check the return value. 您应该检查返回值。
  • It's inefficient to write every character one-character-at-a-time. 一次写一个字符效率不高。 You should consider buffering your output. 您应该考虑缓冲您的输出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM