1. 程式人生 > >printf可變引數的實現

printf可變引數的實現

我是大自然的搬運工。。。。。

print.h

  1. #ifndef     __PRINT_H_
  2. #define    __PRINT_H_
  3. void    print(char* fmt, ...);  
  4. void    printch(char ch);  
  5. void    printdec(int dec);  
  6. void    printflt(double flt);  
  7. void    printbin(int bin);  
  8. void    printhex(int hex);  
  9. void    printstr(char* str);  
  10. #define console_print(ch)    putchar(ch)
  11. #endif    /*#ifndef __PRINT_H_*/

上面print函式為全功能的列印函式,可以實現類似printf的功能,printch實現單個字元的列印、printdec實現十進位制格式數字的列印,printflt實現浮點數的列印,printbin實現二進位制格式數字的列印,printhex實現十六進位制格式數字的列印,printstr實現字串的列印,console_print函式是串列埠單字元列印函式的巨集定義,這裡暫時用PC終端單字元列印函式putchar代替。在實際嵌入式環境下,替換成串列埠單字元列印函式即可。
print.c

  1. #include <stdio.h>
  2. #include <stdarg.h>
  3. #include "print.h"
  4. int main(void)  
  5. {  
  6.     print("print: %c\n"'c');  
  7.     print("print %d\n", 1234567);  
  8.     print("print: %f\n", 1234567.1234567);  
  9.     print("print: %s\n""string test");  
  10.     print("print: %b\n", 0x12345ff);  
  11.     print("print: %x\n", 0xabcdef);  
  12.     print(
    "print: %%\n");  
  13. return 0;  
  14. }  
  15. void    print(char* fmt, ...)  
  16. {  
  17. double vargflt = 0;  
  18. int  vargint = 0;  
  19. char* vargpch = NULL;  
  20. char vargch = 0;  
  21. char* pfmt = NULL;  
  22. va_list vp;  
  23.     va_start(vp, fmt);  
  24.     pfmt = fmt;  
  25. while(*pfmt)  
  26.     {  
  27. if(*pfmt == '%')  
  28.         {  
  29. switch(*(++pfmt))  
  30.             {  
  31. case'c':  
  32.                     vargch = va_arg(vp, int);   
  33. /*    va_arg(ap, type), if type is narrow type (char, short, float) an error is given in strict ANSI 
  34.                         mode, or a warning otherwise.In non-strict ANSI mode, 'type' is allowed to be any expression. */
  35.                     printch(vargch);  
  36. break;  
  37. case'd':  
  38. case'i':  
  39.                     vargint = va_arg(vp, int);  
  40.                     printdec(vargint);  
  41. break;  
  42. case'f':  
  43.                     vargflt = va_arg(vp, double);  
  44. /*    va_arg(ap, type), if type is narrow type (char, short, float) an error is given in strict ANSI 
  45.                         mode, or a warning otherwise.In non-strict ANSI mode, 'type' is allowed to be any expression. */
  46.                     printflt(vargflt);  
  47. break;  
  48. case's':  
  49.                     vargpch = va_arg(vp, char*);  
  50.                     printstr(vargpch);  
  51. break;  
  52. case'b':  
  53. case'B':  
  54.                     vargint = va_arg(vp, int);  
  55.                     printbin(vargint);  
  56. break;  
  57. case'x':  
  58. case'X':  
  59.                     vargint = va_arg(vp, int);  
  60.                     printhex(vargint);  
  61. break;  
  62. case'%':  
  63.                     printch('%');  
  64. break;  
  65. default:  
  66. break;  
  67.             }  
  68.             pfmt++;  
  69.         }  
  70. else
  71.         {  
  72.             printch(*pfmt++);  
  73.         }  
  74.     }  
  75.     va_end(vp);  
  76. }  
  77. void    printch(char ch)  
  78. {  
  79.     console_print(ch);  
  80. }  
  81. void    printdec(int dec)  
  82. {  
  83. if(dec==0)  
  84.     {  
  85. return;  
  86.     }  
  87.     printdec(dec/10);  
  88.     printch( (char)(dec%10 + '0'));  
  89. }  
  90. void    printflt(double flt)  
  91. {  
  92. int icnt = 0;  
  93. int tmpint = 0;  
  94.     tmpint = (int)flt;  
  95.     printdec(tmpint);  
  96.     printch('.');  
  97.     flt = flt - tmpint;  
  98.     tmpint = (int)(flt * 1000000);  
  99.     printdec(tmpint);  
  100. }  
  101. void    printstr(char* str)  
  102. {  
  103. while(*str)  
  104.     {  
  105.         printch(*str++);  
  106.     }  
  107. }  
  108. void    printbin(int bin)  
  109. {  
  110. if(bin == 0)  
  111.     {  
  112.         printstr("0b");  
  113. return;  
  114.     }  
  115.     printbin(bin/2);  
  116.     printch( (char)(bin%2 + '0'));  
  117. }  
  118. void    printhex(int hex)  
  119. {  
  120. if(hex==0)  
  121.     {  
  122.         printstr("0x");  
  123. return;  
  124.     }  
  125.     printhex(hex/16);  
  126. if(hex < 10)  
  127.     {  
  128.         printch((char)(hex%16 + '0'));  
  129. 相關推薦

    printf可變引數實現

    我是大自然的搬運工。。。。。 print.h #ifndef     __PRINT_H_ #define    __PRINT_H_ void    print(char* fmt, ...);   void    printch(char ch);   vo

    如何用 linux 實現命令列引數可變引數實現

    僅用main函式的引數實現一個整數計算器 #include <stdio.h> #include <string.h> #include <stdlib.h>

    理解printf可變引數函式

    瞭解了下可變參函式的原理,這裡記錄下方便自己以後看printf函式原型 int printf(const char *fmt, ...)這裡寫個例子方便理解 printf("%s\n","hello"); 函式傳參引數壓棧的方向是從右往左,也就是說當呼叫printf函式的時候

    通過可變引數實現函式,求函式的平均值

    #include<stdio.h>#include<stdarg.h>#include<Windows.h>#pragma warning (disable :4996)int getaver(int num,...){va_list ar

    05 printf函式可變引數實現原理之彙編分析

    如實現一個像printf函式格式的函式: test.c void myprintf(char *line, ...) // line指標變數是區域性變數,在棧裡分配空間 { printf(line); //呼叫printf時,r0存放字串地

    可變引數列表模擬實現printf函式

    用可變引數列表實現printf函式要實現printf函式,我們首先應該獲取printf函式中由雙引號中的字串,若遇到不是%的字元,我們應該直接將其輸出,若遇到%,我們應該判斷它後面是什麼字元,這裡先只考慮%c,%s的情況,如果是%c那麼我們應該將讀到的字元輸出來,若為%s,應

    【C語言】用可變引數列表實現printf函式

    //用可變引數列表實現printf函式 #include <stdio.h> #include <stdarg.h> void my_printf(const char *st

    模擬實現printf函式,可變引數列表例項

    首先可通過CSDN檢視printf函式原型等資訊 實現功能: Print formatted output to the standard output stream. 即格式化輸出並

    可變引數列表實現簡單的printf函式

    #include<stdio.h> #include<string.h> #include<stdlib.h> #include<stdarg.h> void print_num(int n) { if (

    可變引數列表模擬實現printf函式,可完成下面的功能

    【問題描述】:模擬實現printf函式,可完成下面的功能//能完成下面函式的呼叫。//print("s ccc d.\n","hello",'b','a','t',100);//函式原型://print

    【c語言】用可變引數列表實現一個簡化的printf函式

    //實現一個簡化的printf函式。 #include <stdarg.h> #include <string.h> void my_printf(const char *str,...) { va_list arg; //準備訪問可變引

    可變引數列表(模擬實現printf)

    1.什麼是可變引數列表?通過將函式實現為可變引數的形式,可以使得函式可以接受1個以上的任意多個引數。我們先看一個例子:int average(int n,...) { va_list arg; //相當於宣告一個指標,名字為arg int i =

    可變引數模板--案例2(實現自己的printf

    利用可變模板引數自定義printf函式,直接上程式碼。 /******************************************* * Name:      example2.cpp * Describe:  可變模板引數例項2:重寫printf * Au

    實現自己的printf列印 -- 可變引數的函式

    /*X86平臺,引數傳遞是基於堆疊來完成的,對記憶體使用時連續的*/ void printf_myself(const char *format, ...) { //char *ptr_s = &format; int num; char

    使用可變引數實現函式,求函式引數的平均值

    使用可變引數,實現函式,求函式引數的平均值 程式程式碼如下: #include <stdio.h> #include <stdarg.h> int Average(int n, ...) { va_list arg;

    C/C++中用va_start/va_arg/va_end實現可變引數函式的原理

    C/C++中用va_start/va_arg/va_end實現可變引數函式的原理與例項詳解         在C/C++中,我們經常會用到可變引數的函式(比如printf/snprintf等),本篇筆記旨在講解編譯器藉助va_start/va_arg/va

    可變引數模板實現C++反射

    1. 概要 本文描述一個通過C++可變引數模板實現C++反射機制的方法。該方法非常實用,在Nebula高效能網路框架中大量應用,實現了非常強大的動態載入動態建立功能。Nebula框架在coding.net的倉庫地址。 C++11的新特性–可變模版引數(variadic templat

    C語言 可變引數列表的實現

    使用可變引數列表,可以讓函式在不同場合接收不同數量的引數傳入,printf函式的格式化輸出,就是一個典型的例子。 printf("<格式化字串>", <參量表>);           &

    c語言中可變引數實現

    (一) 寫一個簡單的可變引數的C函式 下面我們來探討,如何寫一個簡單的可變引數的C函式。寫可變引數的C函式要在程式中用到以下這些巨集: void va_start( va_list arg_ptr, prev_param ); type va_arg( va_list

    C可變引數函式 實現

      C函式要在程式中用到以下這些巨集: void va_start( va_list arg_ptr, prev_param ); type va_arg( va_list arg_ptr, type ); void va_end( va_list arg_ptr )