| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1507 人关注过本帖
标题:printf
只看楼主 加入收藏
q201q5
Rank: 1
等 级:新手上路
帖 子:14
专家分:3
注 册:2016-2-23
结帖率:50%
收藏
已结贴  问题点数:20 回复次数:6 
printf
一个小型的printf函数,只需要实现myputs函数。这个代码可以用于嵌入式开发的调试。

程序代码:
#undef ullong
#undef sllong
#undef llong

#define  llong __int64
#define sllong signed llong
#define ullong unsigned llong

const int _my_chartab[256] =
  {
    98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 99, 99, 99, 99, 99, 99,
    99, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
    25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 99, 99, 99, 99, 99,
    99, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
    25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 99, 99, 99, 99, 99,
    99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
  };
const int _my_chartab2[256] =
  {
    98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 99, 99, 99, 99, 99, 99,
    99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    99, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
    25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 99, 99, 99, 99, 99,
    99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
  };
const char _my_tabCHAR[] =
  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
const char _my_tabchar[] =
  "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  
unsigned long myatoul(const char *s, char **endp, int base_)
{
    unsigned long res = 0;
    unsigned c, base = (unsigned)base_;

    if (base < 2) {
        base = 10;
        if (*s == '0') {
            base = 8;
            c = *++s;
            if (c == 'b' || c == 'B') base = 2, ++s;
            else if (c == 'x' || c == 'X') base = 16, ++s;
        }
    }

    for (; (c = _my_chartab[(int)*s]) < base; ++s)
        res = res * base + c;
    if (endp)
        *endp = (char*)s;
    return res;
}

int mystrlen(const char *s)
{
    const char *s0 = s;
    while (*s) ++s;
    return s - s0;
}


#define FLAGS_FILL     (1U << 0)
#define FLAGS_PREFIX   (1U << 1)
#define FLAGS_SPEC     (1U << 2)
#define FLAGS_ADD      (1U << 3)
#define FLAGS_ADDR     (1U << 4)
#define FLAGS_LEFT     (1U << 6)
#define FLAGS_SIGN     (1U << 7)
#define FLAGS_UNSIGNED (1U << 8)
#define FLAGS_UPPER    (1U << 9)
#define FLAGS_SIGNED   (1U << 10)

extern const int  _my_chartab[];
extern const char _my_tabCHAR[];
extern const char _my_tabchar[];


struct vsprintf_status {
    unsigned flags;
    int width;
    int base;
    int prec;
    int filled;
    int nrl, nrh;
    ullong value;
    char sign;

    char buffer[128];
    int nlen;
    const char *ptrout;
    const char *prefix;
};

static void init_status(struct vsprintf_status *st)
{
    st->flags = 0;
    st->width = 0;
    st->base = 10;
    st->prec = 1000000;
    st->filled = ' ';
    st->value = 0;
    st->nrl = st->nrh = 0;
    st->nlen = 0;
    st->sign = 0;
    st->ptrout = "";
    st->prefix = "";
}

int myvsprintf(char *dst, const char *fmt_, va_list ap)
{
    char *dst_orig = dst, *cp;
    struct vsprintf_status st;
    unsigned long ulval;
    const char *p_chartab, *str;
    int c, i, tmpi, align;
    ullong uval;
    const unsigned char *fmt = (const unsigned char *)fmt_;
    
repeat:
    switch((c = *fmt++)) {
    case 0:   goto finsh;
    default:  *dst++ = c; goto repeat;
    case '%': break;
    }
    
    init_status(&st);

spec:
    switch((c = *fmt++)) {
    case '+': st.flags |= FLAGS_ADD;  goto spec;
    case '-': st.flags |= FLAGS_LEFT; goto spec;
    case '#': st.flags |= FLAGS_SPEC; goto spec;
    case '%': *dst++ = c; goto repeat;
    default: break;
    }
    
    if (c == '0') {
        st.filled = '0';
        c = *fmt++;
    }

    if (c == '*')
        st.width = va_arg(ap, int), c = *fmt++;
    else if (_my_chartab[c] <= 9)
        st.width = myatoul ((const char*)(fmt-1), (char**)&fmt, 10), c = *fmt++;
    
    if (c == '.') {
        if ((c = *fmt++) == '*')
            st.prec = va_arg(ap, int), c = *fmt++;
        else if (_my_chartab[c] <= 9)
            st.prec = myatoul((const char*)(fmt-1), (char**)&fmt, 10), c = *fmt++;
    }
    
    if (c == 'l' || c == 'L') st.nrl++, c = *fmt++;
    else if (c == 'h' || c == 'H') st.nrh++, c = *fmt++;
    
    if (c == 'l' || c == 'L') st.nrl++, c = *fmt++;
    else if (c == 'h' || c == 'H') st.nrh++, c = *fmt++;

    switch(c) {
    default: goto repeat;
    case 0:  goto finsh;
    
    case 'c': st.buffer[0] = va_arg (ap, int);
              st.buffer[1] = 0;
              st.ptrout = st.buffer;
              st.nlen = 1;
              goto print_string;
              
    case 's': st.ptrout = va_arg (ap, const char *);
              if (st.ptrout == NULL) {
                  st.ptrout = "(NULL)";
                  st.nlen = 6;
                  st.filled = ' ';
                  goto print_string;
              }
              st.nlen = mystrlen(st.ptrout);
              goto print_string;
              
    case 'B': st.flags |= FLAGS_UPPER;
    case 'b': st.base = 2;
              goto get_and_print_int;
    case 'X': st.flags |= FLAGS_UPPER;
    case 'x': st.base = 16;
              goto get_and_print_int;
    case 'O': st.flags |= FLAGS_UPPER;
    case 'o': st.base = 8;
              goto get_and_print_int;
    case 'U': st.flags |= FLAGS_UPPER;
    case 'u':
              goto get_and_print_int;
    case 'd':
    case 'i': st.flags |= FLAGS_SIGNED;
              goto get_and_print_int;
              
    case 'P': st.flags |= FLAGS_UPPER;
    case 'p': st.base = 16;
              st.width = sizeof (void *) * 2;
              st.filled = '0';
              st.value = (unsigned long) va_arg (ap, void*);
              if (st.value == (unsigned long)(NULL)) {
                  st.ptrout = "NULL";
                  st.nlen = 4;
                  st.filled = ' ';
                  goto print_string;
              }
              goto print_ptr_int;
    }
    
get_and_print_int:
    if (st.base < 2 || st.base > 16)
        st.base = 16;
    switch(st.nrl) {
    case 2: st.value = va_arg(ap, ullong);
            if ((st.flags & FLAGS_SIGNED) && (sllong)st.value < 0)
                st.sign = '-', st.value = (ullong)-(sllong)st.value;
            break;
    case 1: st.value = va_arg(ap, unsigned long);
            if ((st.flags & FLAGS_SIGNED) && (signed long)st.value < 0)
                st.sign = '-', st.value = (unsigned long)-(signed long)st.value;
            break;
    case 0: st.value = va_arg(ap, unsigned);
            if ((st.flags & FLAGS_SIGNED) && (signed)st.value < 0)
                st.sign = '-', st.value = (unsigned)-(signed)st.value;
            if (st.nrh == 2) st.value &= 0xFF;
            else if (st.nrh == 1) st.value &= 0xFFFF;
            break;
    }
    
print_ptr_int:
    if (st.width > st.prec)
        st.width = st.prec;
    if (st.sign == 0 && (st.flags & FLAGS_ADD))
        st.sign = '+';
    if (st.width > (int)(sizeof (st.buffer) - 8))
        st.width = sizeof (st.buffer) - 8;

    cp = st.buffer + sizeof (st.buffer) - 1;
    *cp = 0;
    p_chartab = _my_tabchar;
    if (st.flags & FLAGS_UPPER)
        p_chartab = _my_tabCHAR;
    uval = st.value;
    i = 0;

    do {
        ++i;
        *--cp = p_chartab[uval % st.base];
    } while ((uval /= st.base) != 0);

    if (st.sign) i++;
    if ((st.flags & FLAGS_SPEC)) {
        if (st.base == 8 && *cp != 0) ++i, st.prefix = "0";
        else if (st.base == 2) {
            i += 2;
            st.prefix = (st.flags & FLAGS_UPPER) ? "B0" : "b0";
        }else if (st.base == 16) {
            i += 2;
            st.prefix = (st.flags & FLAGS_UPPER) ? "X0" : "x0";
        }
    }

    if (st.filled == '0' && i < st.width) {
        for (; i < st.width; ++i)
            *--cp = st.filled;
    }
    if (st.prefix != NULL && st.prefix[0] != 0) {
        for (str = st.prefix; *str; ++str)
            *--cp = *str;
    }
    if (st.sign != 0)
        *--cp = st.sign;
    st.nlen = i;
    st.ptrout = cp;
    goto print_string;

print_string:
    align = 0;
    if (st.nlen > st.prec)
        st.nlen = st.prec;
    if (st.width > st.nlen)
        align = st.width - st.nlen;
    if ((st.flags & FLAGS_LEFT) == 0)
        for (; align > 0; --align)
            *dst++ = st.filled;
    for (i = 0; i < st.nlen; ++i)
        *dst++ = st.ptrout[i];
    for (; align > 0; --align)
        *dst++ = st.filled;
    goto repeat;
    
finsh:
    *dst++ = 0;
    return 0;
}

int myprintf(const char *fmt, ...)
{
    int res;
    va_list ap;
    char buff[256];

    va_start(ap, fmt);
    res = myvsprintf(buff, fmt, ap);
    va_end(ap);
    myputs(buff);

    return res;
}

int mysprintf(char *s, const char *fmt, ...)
{
    int res;
    va_list ap;

    va_start(ap, fmt);
    res = myvsprintf(s, fmt, ap);
    va_end(ap);

    return res;
}
搜索更多相关主题的帖子: 嵌入式开发 color 
2016-03-13 11:22
qq1023569223
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:湖南科技大学
等 级:贵宾
威 望:26
帖 子:2753
专家分:13404
注 册:2010-12-22
收藏
得分:4 
好贴,帮顶了。

   唯实惟新 至诚致志
2016-03-13 12:38
Redeyes
Rank: 4
来 自:中国
等 级:业余侠客
威 望:1
帖 子:301
专家分:292
注 册:2015-5-13
收藏
得分:4 
看到该帖的第一感觉就是代码好长。虽然我是学计算机硬件方向的,但还没接触到关于嵌入式开发的调试,所以——帮你顶一下喽!

做一名健壮的技术青年,如果未来无法用代码去改变世界,还可以考虑去搬砖。
2016-03-18 10:55
grmmylbs
Rank: 14Rank: 14Rank: 14Rank: 14
等 级:贵宾
威 望:54
帖 子:1409
专家分:5845
注 册:2016-2-14
收藏
得分:4 
myputs未定义
2016-03-18 11:27
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:4 
現在的嵌入式需要這樣做的嗎?

授人以渔,不授人以鱼。
2016-03-18 12:50
lautition
Rank: 2
等 级:论坛游民
威 望:1
帖 子:24
专家分:21
注 册:2016-3-16
收藏
得分:4 
这个距离我还太遥远,帮定下
2016-03-18 14:28
李晨曦
Rank: 2
等 级:论坛游民
帖 子:16
专家分:10
注 册:2016-3-21
收藏
得分:0 
刚学c,看着这个眼睛都瞎了
2016-03-21 21:43
快速回复:printf
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.033697 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved