Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1176916
  • 博文数量: 573
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 66
  • 用 户 组: 普通用户
  • 注册时间: 2016-06-28 16:21
文章分类

全部博文(573)

文章存档

2018年(3)

2016年(48)

2015年(522)

分类: C/C++

2015-12-02 16:46:58

使用c库头文件实现sprintf函数

点击(此处)折叠或打开

  1. #include <string.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <stdarg.h>

  5. int myprintf(const char * format, ...)
  6. {
  7.     va_list ap;
  8.     int ret = -1;
  9.     va_start(ap, format);
  10.     ret = vprintf(format, ap);
  11.     va_end(ap);
  12.     return ret;
  13. }

  14. int mysprintf(char * str, const char * format, ...)
  15. {
  16.     va_list ap;
  17.     int ret = -1;
  18.     va_start(ap, format);
  19.     ret = vsprintf(str, format, ap);
  20.     va_end(ap);
  21.     return ret;
  22. }

  23. int main(int argc, char ** argv)
  24. {
  25.     int    s, l;
  26.     int index1 = 30123456;
  27.     int index2 = 123;
  28.     char    a[5];
  29.     char    b[5];
  30.     char c[12];
  31.     memset(a, 0x00, sizeof(a));
  32.     memset(b, 0x00, sizeof(b));
  33.     memset(c, 0x00, sizeof(c));
  34.     s = snprintf( a, 2, "%d", index2 );
  35.     l = sprintf(b, "%d", index2);
  36.     myprintf("s = [%d], l = [%d]\n", s, l);
  37.     myprintf("a = [%s], b = [%s]\n", a, b);
  38.     mysprintf(c, "%s", "自定义变参函数!");
  39.     printf("c = [%s]\n", c);
  40.     return 0;
  41. }
不使用c库实现sprintf函数

点击(此处)折叠或打开

  1. #include <stdio.h>

  2. typedef char * va_list;
  3. #define va_start(ap,p) (ap = (char *) (&(p)+1))
  4. #define va_arg(ap, type) ((type *) (ap += sizeof(type)))[-1]
  5. #define va_end(ap)

  6. char * strcpy(char * dest,const char *src);
  7. char * strcat(char * dest, const char * src);
  8. unsigned int strlen(const char * s);
  9. void * memset(void * s,int c,unsigned int count);
  10. void * memcpy(void * dest,const void *src,unsigned int count);
  11. int sprintf(char * str, const char *fmt, ...);
  12. void itoa(unsigned int n, char * buf);
  13. int atoi(char* pstr);
  14. void xtoa(unsigned int n, char * buf);
  15. int isDigit(unsigned char c);
  16. int isLetter(unsigned char c);


  17. int main(int argc, char * * argv)
  18. {
  19.         int num = 12;
  20.         char buf[128];
  21.         int hex_num = 15;
  22.         char str[256];
  23.         
  24.         memset(str, 0, sizeof(str));
  25.         memset(buf, 0, sizeof(buf));
  26.         strcpy(buf, "time out");

  27.         printf("OK!\n");
  28.         printf("num=[%d]\n", num);
  29.         printf("buf=[%s]\n", buf);
  30.         printf("hex_num=[%x]\n", hex_num);
  31.     
  32.         sprintf(str, "num=[%d], buf=[%s], hex_num=[%x]", num, buf, hex_num);

  33.         printf("str=[%s]\n", str);

  34.         return 0;
  35. }



  36. /*功能:向字符串 格式化打印一个字符串
  37. *参数:格式化的字符串
  38. *注意:这个是简易版本 (%02x 完成)
  39. * %-3s不行, %f也不行, %X不行
  40. */
  41. int sprintf(char * str, const char *fmt, ...)
  42. {
  43.     int count = 0;
  44.     char c;
  45.     char *s;
  46.     int n;
  47.     
  48.     int index = 0;
  49.     int ret = 2;
  50.     
  51.     char buf[65];
  52.     char digit[16];
  53.     int num = 0;
  54.     int len = 0;
  55.     
  56.     memset(buf, 0, sizeof(buf));
  57.     memset(digit, 0, sizeof(digit));

  58.     va_list ap;
  59.     
  60.     va_start(ap, fmt);
  61.     
  62.     while(*fmt != '\0')
  63.     {
  64.         printf("*fmt=[%c]\n", *fmt);
  65.         if(*fmt == '%')
  66.         {
  67.             fmt++;
  68.             switch(*fmt)
  69.          {
  70.                 case 'd': /*整型*/
  71.                 {
  72.                         n = va_arg(ap, int);
  73.                         if(n < 0)
  74.                         {
  75.                             *str = '-';
  76.                             str++;
  77.                             n = -n;
  78.                         }
  79.                         printf("case d n=[%d]\n", n);
  80.                         itoa(n, buf);
  81.                         printf("case d buf=[%s]\n", buf);
  82.                         memcpy(str, buf, strlen(buf));
  83.                         str += strlen(buf);
  84.                         break;
  85.                 }    
  86.                 case 'c': /*字符型*/
  87.                 {
  88.                         c = va_arg(ap, int);
  89.                         *str = c;
  90.                         str++;
  91.                         
  92.                         break;
  93.                 }
  94.                 case 'x': /*16进制*/
  95.                 {
  96.                         n = va_arg(ap, int);
  97.                         xtoa(n, buf);
  98.                         memcpy(str, buf, strlen(buf));
  99.                         str += strlen(buf);
  100.                         break;
  101.                 }
  102.                 case 's': /*字符串*/
  103.                 {
  104.                         s = va_arg(ap, char *);
  105.                         memcpy(str, s, strlen(s));
  106.                         str += strlen(s);
  107.                         break;
  108.                 }
  109.                 case '%': /*输出%*/
  110.                 {
  111.                     *str = '%';
  112.                     str++;
  113.                     
  114.                     break;
  115.                 }
  116.                 case '0': /*位不足的左补0*/
  117.                 {
  118.                         index = 0;
  119.                         num = 0;
  120.                         memset(digit, 0, sizeof(digit));
  121.                         
  122.                         while(1)
  123.                         {
  124.                                 fmt++;
  125.                                 ret = isDigit(*fmt);
  126.                                 if(ret == 1) //是数字
  127.                                 {
  128.                                         digit[index] = *fmt;
  129.                                         index++;
  130.                                 }
  131.                                 else
  132.                                 {
  133.                                         num = atoi(digit);
  134.                                         break;
  135.                                 }
  136.                         }
  137.                         switch(*fmt)
  138.                      {
  139.                                 case 'd': /*整型*/
  140.                                 {
  141.                                         n = va_arg(ap, int);
  142.                                         if(n < 0)
  143.                                         {
  144.                                             *str = '-';
  145.                                             str++;
  146.                                             n = -n;
  147.                                         }    
  148.                                         itoa(n, buf);
  149.                                         len = strlen(buf);
  150.                                         if(len >= num)
  151.                                         {
  152.                                                 memcpy(str, buf, strlen(buf));
  153.                                                 str += strlen(buf);
  154.                                         }
  155.                                         else
  156.                                         {
  157.                                                 memset(str, '0', num-len);
  158.                                                 str += num-len;
  159.                                                 memcpy(str, buf, strlen(buf));
  160.                                                 str += strlen(buf);
  161.                                         }
  162.                                         break;
  163.                                 }    
  164.                                 case 'x': /*16进制*/
  165.                                 {
  166.                                         n = va_arg(ap, int);
  167.                                         xtoa(n, buf);
  168.                                         len = strlen(buf);
  169.                                         if(len >= num)
  170.                                         {
  171.                                                 memcpy(str, buf, len);
  172.                                                 str += len;
  173.                                         }            
  174.                                         else
  175.                                         {
  176.                                                 memset(str, '0', num-len);
  177.                                                 str += num-len;
  178.                                                 memcpy(str, buf, len);
  179.                                                 str += len;
  180.                                         }
  181.                                         break;
  182.                                 }
  183.                                 case 's': /*字符串*/
  184.                                 {
  185.                                         s = va_arg(ap, char *);
  186.                                         len = strlen(s);
  187.                                         if(len >= num)
  188.                                         {
  189.                                                 memcpy(str, s, strlen(s));
  190.                                                 str += strlen(s);
  191.                                         }
  192.                                         else
  193.                                         {
  194.                                                 memset(str, '0', num-len);
  195.                                                 str += num-len;
  196.                                                 memcpy(str, s, strlen(s));
  197.                                                 str += strlen(s);
  198.                                         }
  199.                                         break;
  200.                                 }
  201.                                 default:
  202.                                         break;
  203.                         }
  204.                 }
  205.                 default:
  206.                         break;
  207.             }
  208.         }
  209.         else
  210.         {
  211.             *str = *fmt;
  212.             str++;
  213.             
  214.             if(*fmt == '\n')
  215.             {
  216.                     
  217.             }
  218.         }
  219.         fmt++;
  220.     }

  221.     va_end(ap);

  222.     return count;
  223. }

  224. /*
  225. *功能:整型(int) 转化成 字符型(char)
  226. *注意:不用 % / 符号的话,只能正确打印:0...9的数字对应的字符'0'...'9'
  227. */
  228. void itoa(unsigned int n, char * buf)
  229. {
  230.         int i;
  231.         
  232.         if(n < 10)
  233.         {
  234.                 buf[0] = n + '0';
  235.                 buf[1] = '\0';
  236.                 return;
  237.         }
  238.         itoa(n / 10, buf);

  239.         for(i=0; buf[i]!='\0'; i++);
  240.         
  241.         buf[i] = (n % 10) + '0';
  242.         
  243.         buf[i+1] = '\0';
  244. }

  245. /*
  246. *功能:字符型(char) 转化成 整型(int)
  247. */
  248. int atoi(char* pstr)
  249. {
  250.         int int_ret = 0;
  251.         int int_sign = 1; //正负号标示 1:正数 -1:负数
  252.         
  253.         if(pstr == '\0') //判断指针是否为空
  254.         {
  255.                 return -1;
  256.         }
  257.         while(((*pstr) == ' ') || ((*pstr) == '\n') || ((*pstr) == '\t') || ((*pstr) == '\b'))
  258.         {
  259.                 pstr++; //跳过前面的空格字符
  260.         }
  261.         
  262.         /*
  263.         * 判断正负号
  264.         * 如果是正号,指针指向下一个字符
  265.         * 如果是符号,把符号标记为Integer_sign置-1,然后再把指针指向下一个字符
  266.         */
  267.         if(*pstr == '-')
  268.         {
  269.                 int_sign = -1;
  270.         }
  271.         if(*pstr == '-' || *pstr == '+')
  272.         {
  273.                 pstr++;
  274.         }
  275.         
  276.         while(*pstr >= '0' && *pstr <= '9') //把数字字符串逐个转换成整数,并把最后转换好的整数赋给Ret_Integer
  277.         {
  278.                 int_ret = int_ret * 10 + *pstr - '0';
  279.                 pstr++;
  280.         }
  281.         int_ret = int_sign * int_ret;
  282.         
  283.         return int_ret;
  284. }

  285. /*
  286. *功能:16进制字(0x) 转化成 字符型(char)
  287. *注意:不用 % / 符号的话,只能正确打印,0...9..15的数字,对应的'0'...'9''A'...'F'
  288. *注意:由于编译问题,这个函数,暂时由uart_sendByte_hex()函数替代
  289. */
  290. void xtoa(unsigned int n, char * buf)
  291. {
  292.         int i;
  293.         
  294.         if(n < 16)
  295.         {
  296.                 if(n < 10)
  297.                 {
  298.                         buf[0] = n + '0';
  299.                 }
  300.                 else
  301.                 {
  302.                         buf[0] = n - 10 + 'a';
  303.                 }
  304.                 buf[1] = '\0';
  305.                 return;
  306.         }
  307.         xtoa(n / 16, buf);
  308.         
  309.         for(i = 0; buf[i] != '\0'; i++);
  310.         
  311.         if((n % 16) < 10)
  312.         {
  313.                 buf[i] = (n % 16) + '0';
  314.         }
  315.         else
  316.         {
  317.                 buf[i] = (n % 16) - 10 + 'a';
  318.         }
  319.         buf[i + 1] = '\0';
  320. }

  321. /*
  322.  * 判断一个字符是否数字
  323.  */
  324. int isDigit(unsigned char c)
  325. {
  326.     if (c >= '0' && c <= '9')
  327.         return 1;
  328.     else
  329.         return 0;
  330. }

  331. /*
  332.  * 判断一个字符是否英文字母
  333.  */
  334. int isLetter(unsigned char c)
  335. {
  336.     if (c >= 'a' && c <= 'z')
  337.         return 1;
  338.     else if (c >= 'A' && c <= 'Z')
  339.         return 1;
  340.     else
  341.         return 0;
  342. }

  343. /**
  344.  * memset - Fill a region of memory with the given value
  345.  * @s: Pointer to the start of the area.
  346.  * @c: The byte to fill the area with
  347.  * @count: The size of the area.
  348.  *
  349.  * Do not use memset() to access IO space, use memset_io() instead.
  350.  */
  351. void * memset(void * s,int c,unsigned int count)
  352. {
  353.     char *xs = (char *) s;

  354.     while (count--)
  355.         *xs++ = c;

  356.     return s;
  357. }

  358. /**
  359.  * strcpy - Copy a %NUL terminated string
  360.  * @dest: Where to copy the string to
  361.  * @src: Where to copy the string from
  362.  */
  363. char * strcpy(char * dest,const char *src)
  364. {
  365.     char *tmp = dest;

  366.     while ((*dest++ = *src++) != '\0')
  367.         /* nothing */;
  368.     return tmp;
  369. }


  370. /**
  371.  * strlen - Find the length of a string
  372.  * @s: The string to be sized
  373.  */
  374. unsigned int strlen(const char * s)
  375. {
  376.     const char *sc;

  377.     for (sc = s; *sc != '\0'; ++sc)
  378.         /* nothing */;
  379.     return sc - s;
  380. }

  381. /**
  382.  * strcat - Append one %NUL-terminated string to another
  383.  * @dest: The string to be appended to
  384.  * @src: The string to append to it
  385.  */
  386. char * strcat(char * dest, const char * src)
  387. {
  388.     char *tmp = dest;

  389.     while (*dest)
  390.         dest++;
  391.     while ((*dest++ = *src++) != '\0')
  392.         ;

  393.     return tmp;
  394. }

阅读(11455) | 评论(0) | 转发(0) |
0

上一篇:rename函数

下一篇:ntohl,htonl函数

给主人留下些什么吧!~~