来自:https://www.cnblogs.com/02xiaoma/archive/2012/06/22/2558618.html

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

int main(void)
{
  print("print: %c\n", 'c');
  print("print %d\n", 1234567);
  print("print: %f\n", 1234567.1234567);
  print("print: %s\n", "string test");
  print("print: %b\n", 0x12345ff);
  print("print: %x\n", 0xabcdef);
  print("print: %%\n");
  return 0;
}

void print(char* fmt, ...)
{
  double vargflt = 0;
  int vargint = 0;
  char* vargpch = NULL;
  char vargch = 0;
  char* pfmt = NULL;
  va_list vp;

  va_start(vp, fmt);
  pfmt = fmt;

while(*pfmt)
{
  if(*pfmt == '%')
  {
    switch(*(++pfmt))
    {

      case 'c':
      vargch = va_arg(vp, int);
      /* va_arg(ap, type), if type is narrow type (char, short, float) an error is given in strict ANSI
          mode, or a warning otherwise.In non-strict ANSI mode, 'type' is allowed to be any expression. */
      printch(vargch);
      break;
    case 'd':
    case 'i':
    vargint = va_arg(vp, int);
    printdec(vargint);
    break;
    case 'f':
    vargflt = va_arg(vp, double);
    /* va_arg(ap, type), if type is narrow type (char, short, float) an error is given in strict ANSI
    mode, or a warning otherwise.In non-strict ANSI mode, 'type' is allowed to be any expression. */
    printflt(vargflt);
    break;
    case 's':
      vargpch = va_arg(vp, char*);
      printstr(vargpch);
    break;
    case 'b':
    case 'B':
      vargint = va_arg(vp, int);
      printbin(vargint);
    break;
    case 'x':
    case 'X':
      vargint = va_arg(vp, int);
      printhex(vargint);
    break;
    case '%':
      printch('%');
    break;
    default:
    break;
  }
  pfmt++;
  }
  else
  {
    printch(*pfmt++);
  }
  }
  va_end(vp);
}

void printch(char ch)
{
  console_print(ch);
}

void printdec(int dec)
{
  if(dec==0)
  {
    return;
  }
  printdec(dec/10);

  {
    printch( (char)(dec%10 + '0'));
  }

void printflt(double flt)
{
  int icnt = 0;
  int tmpint = 0;

  tmpint = (int)flt;
  printdec(tmpint);
  printch('.');
  flt = flt - tmpint;
  tmpint = (int)(flt * 1000000);
  printdec(tmpint);
}

void printstr(char* str)
{
  while(*str)
  {
    printch(*str++);
  }
}

void printbin(int bin)
{
  if(bin == 0)
  {
    printstr("0b");
    return;
  }
  printbin(bin/2);
  printch( (char)(bin%2 + '0'));
}

void printhex(int hex)
{
  if(hex==0)
  {
    printstr("0x");
    return;
  }
  printhex(hex/16);
  if(hex < 10)
  {
    printch((char)(hex%16 + '0'));
  }
  else
  {
    printch((char)(hex%16 - 10 + 'a' ));
  }
}

嵌入式 printf函数的更多相关文章

  1. 可变参数列表与printf()函数的实现

    问题 当我们刚开始学习C语言的时候,就接触到printf()函数,可是当时"道行"不深或许不够细心留意,又或者我们理所当然地认为库函数规定这样就是这样,没有发现这个函数与普通的函数 ...

  2. printf函数

    printf函数的格式及含义 d                    以十进制带符号的形式输出整数(对正数不输出符号) o                    以八进制无符号的形式输出整数(不输出 ...

  3. Linux Linux下特殊的printf函数和fputs函数

    Linux下,printf函数必须以'\n'结尾才会立刻输出到屏幕,如果没有'\n'直到输出缓冲区满了以后才会打印到屏幕上(敲击换行也算),如果需要不换行的输出,一般可以使用write函数代替.'\n ...

  4. 关于printf函数的所思所想

    缘起大一下学期,C语言程序设计徐小青老师的随口一提,经娄嘉鹏老师提醒,我觉得应该自己整理清楚这一问题.涉及网上资料将会标明出处. 关于printf函数的所思所想 * printf的定义 printf( ...

  5. C语言printf()函数:格式化输出函数

    C语言printf()函数:格式化输出函数 头文件:#include <stdio.h> printf()函数是最常用的格式化输出函数,其原型为:     int printf( char ...

  6. 关于printf函数输出先后顺序的讲解!!

    对于printf函数printf("%d%d\n",a,b);函数的实际输出顺序是这样的先计算出b,然后在计算a,接着输出a,最后在输出b:例子如下:#include<ios ...

  7. printf()函数

    printf()函数是格式化输出函数, 一般用于向标准输出设备按规定格式输出信息. printf()函数的调用格式为: printf("<格式化字符串>", <参 ...

  8. C 中 关于printf 函数中度剖析

    题外话  这篇博文主要围绕printf函数分析的,主要讲解printf 使用C的可变参数机制, printf是否可重入(是否线程安全), printf函数的源码实现. 正文 1.C中可变参数机制 我们 ...

  9. printf函数重定向

    printf函数底层会调用fputc函数 /*重定向c库函数printf到USART1*/ int fputc(int ch, FILE *f) { /*发送一个字节数据USART1 */ USART ...

随机推荐

  1. 浅谈MVC中的service层(转)

    概述 mvc框架由model,view,controller组成,执行流程一般是:在controller访问model获取数据,通过view渲染页面. mvc模式是web开发中的基础模式,采用的是分层 ...

  2. 【leetcode】476. Number Complement

    problem 476. Number Complement solution1: class Solution { public: int findComplement(int num) { //正 ...

  3. excel 格式化姓名

                在做excel时,难免会遇到输入姓名对齐这种情况,如果数据少时我们可以手动敲空格来进行对齐,但数据量大时,手动调整就不是好办法了.     此时我们可以通过excel自带公式对 ...

  4. jmeter 测试MD5加密登录接口

    1.点击options-funciton helper dialog,打开函数助手 在string to  calculate MD5 hash 中填写密码,复制function sysntax中的值 ...

  5. python 面试题1

    1.大数据的文件读取 ① 利用生成器generator ②迭代器进行迭代遍历:for line in file 2.迭代器和生成器的区别 1)迭代器是一个更抽象的概念,任何对象,如果它的类有next方 ...

  6. Image Widget 的几种加入形式

    image .asset : 加载资源图片,会使打包时包体过大 image.network :网络资源图片,经常换的或者动态的图片 image file : 本地图片,比如相册 重用属性:  fit ...

  7. JS之clientX,clientY,screenX,screenY,offsetX,offsetY区别

    首先需要知道clientX,clientY,screenX,screenY,offsetX,offsetY 是鼠标事件对象下的几个属性. 之前也一直对这些属性搞的稀里糊涂,看文档上说的也是不太理解,反 ...

  8. JS如何充分“压榨”浏览器

    不同浏览器厂商实现的 JS 标准有所不同,这意味着 window 对象和可用的 api 也有所不同,希望不久的将来,所有浏览器都能实现统一的 JS 标准. 自己写 api 是很耗费时间跟精力的,而且变 ...

  9. Pagedown learning notes

    Pagedown Links Google wiki page Download Markdown.Converter.js var converter = new Markdown.Converte ...

  10. 芯灵思Sinlinx A64开发板 Linux内核等待队列poll ---阻塞与非阻塞

    开发平台 芯灵思Sinlinx A64 内存: 1GB 存储: 4GB 开发板详细参数 https://m.tb.cn/h.3wMaSKm 开发板交流群 641395230 阻塞:阻塞调用是指调用结果 ...