来自: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. c++学习中的疑问

    1.关于iostream头文件中的cout对象没有包含对string的<<操作符重载函数 测试代码: #include<iostream> using namespace st ...

  2. ubuntu下编译小知识点

    #改变编译器选项 SET(CMAKE_C_COMPILER"g++") #出现如下错误:添加C++11特性 #error: #error This file requires co ...

  3. margin外边距属性

    外边距属性: 设置元素与元素之间的距离(外边距),4个方向(上右下左). margin:长度值|百分比|auto margin-top margin-right margin-bottom margi ...

  4. Python全栈之路----常用模块----shutil模块

    高级的 文件.文件包.压缩包 处理模块   参考Python之路[第四篇]:模块     #src是原文件名,fdst是新文件名 shutil.copyfileobj(fsrc, fdst[, len ...

  5. python中shelve模块的使用

    import shelve # 将序列化文件操作dump与load进行封装,写入文件的内容就是个大的字符串字典 s_dic = shelve.open("text/b.txt",w ...

  6. LeetCode 104. Maximum Depth of Binary Tree C++ 解题报告

    104. Maximum Depth of Binary Tree -- Easy 方法 使用递归 /** * Definition for a binary tree node. * struct ...

  7. 手机响应式echarts

    // 基于准备好的dom,初始化echarts实例var myChart = echarts.init(document.getElementById('main'));// 使用刚指定的配置项和数据 ...

  8. SOFARPC —— Generic Service (泛化调用) 解析

    今晚心情无比激动,多云转晴!原因在于弄懂些 Generic Service 实现原理,很有成就感. 各位看官莫笑,今晚,小小的收获,也是非常满足的.下面进入正题! 一.前言 普遍RPC在客户端需要提供 ...

  9. 引擎设计跟踪(九.14.3.3) Deferred shading的一些小细节

    1.ambient light 之前的shader里面, 方向光会加上ambient 的计算. 但是如果没有方向光, 就没有ambient. 这是把全局方向光改为点光源之后发现的, 因为透明物体的fo ...

  10. PythonStudy——生成器

    # 生成器:自定义的迭代器对象 # -- 就是用函数语法来声明生成器,用yield关键字取代return关键字来返回值,参数没有多少变化 # 总结:有yield关键字的函数,函数名() 不是调用函数, ...