Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4785861
  • 博文数量: 22
  • 博客积分: 731
  • 博客等级: 军士长
  • 技术积分: 260
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-25 17:53
个人简介

技术宅,开源软件爱好者 虚拟机,编译器,编辑器,MCU IP,数据结构,操作系统,TCP/IP协议

文章分类

全部博文(22)

文章存档

2015年(1)

2014年(2)

2013年(2)

2011年(4)

2010年(13)

分类: C/C++

2014-02-22 01:20:04

C标准库中有sprintf和sscan两个函数,可以非常方便的将变量格式化到字符串中,或从字符串中提取数值存放在变量中。
在协议的封装时,如果有函数可以方便的从数值中按指定的格式提取到变量中(协议解析)或从把变量按指定的格式存放在数值中(协议的封包),那将是一件方便的事情。


就我的经验没有见过类似的函数,自己简单实现了一个。欢迎评论和交流。
暂且起个名字叫bprintf和bscan。b (bin或bytearray)

代码如下:

点击(此处)折叠或打开

  1. *****************************************************************************/
  2. * Contact information:
    * sites: mailan7749.blog.chinaunix.net
    *      
    * e-mail:  mailan2008@qq.com
    *****************************************************************************/


  3. #include <stdarg.h>
  4. #include <stdio.h>

  5. typedef unsigned char    INT8U;
  6. typedef unsigned short    INT16U;
  7. typedef unsigned int    INT32U;

  8. /**
  9.  * @brief 类printf,将变量按指定的格式fmt,存放在buf中。
  10.  *
  11.  * @param buf:存放被格式化的数据
  12.  * @param fmt:格式化字符串
  13.  *
  14.  */
  15. char bprintf(INT8U * buf, const char * fmt, ...)
  16. {
  17.     char len;
  18.     char type;
  19.     INT8U data_8;
  20.     INT16U data_16;
  21.     INT32U data_32;
  22.     va_list argp;

  23.     if ( (buf == NULL) || (fmt == NULL) )
  24.         return -1;

  25.     va_start(argp, fmt);
  26.     while(*fmt != 0)
  27.     {
  28.         if (*fmt == ' ')
  29.         {
  30.             fmt ++;
  31.         }
  32.         else if (*fmt == '%')
  33.         {
  34.             len = fmt[1] ;
  35.             type = fmt[2];
  36.             if ( type != 'x' )
  37.                 return -1;
  38.             switch(len)
  39.             {
  40.             case '1':
  41.                 data_8 = va_arg(argp, INT8U);
  42.                 *buf++ = data_8;
  43.                 break;
  44.             case '2':
  45.                 data_16 = va_arg(argp, INT16U);
  46.                 *buf++ = (data_16 >> 8) & 0xFF;
  47.                 *buf++ = data_16 & 0xFF;
  48.                 break;
  49.             case '4':
  50.                 data_32 = va_arg(argp, INT32U);
  51.                 *buf++ = (data_32 >> 24) & 0xFF;
  52.                 *buf++ = (data_32 >> 16) & 0xFF;
  53.                 *buf++ = (data_32 >> 8) & 0xFF;
  54.                 *buf++ = data_32 & 0xFF;
  55.                 break;
  56.             default:
  57.                 return -1;
  58.                 break;
  59.             }
  60.             fmt += 3;
  61.         }        
  62.         else
  63.         {
  64.             *buf = (INT8U)( (fmt[0] - '0') << 4 ) + ( fmt[1] - '0' );
  65.             fmt += 2;
  66.             buf ++;
  67.         }        
  68.     }
  69.     va_end(argp);
  70.     return 0;
  71. }

  72. /**
  73.  * @brief 类scan,将buf中的数据按指定的格式fmt,存放在变量中。
  74.  *
  75.  * @param buf:存放被格式化的数据
  76.  * @param fmt:格式化字符串
  77.  *
  78.  */
  79. char bscan(INT8U * buf, const char *fmt, ...)
  80. {
  81.     void * p;
  82.     char len;
  83.     char type;
  84.     va_list argp;

  85.     if ( (buf == NULL) || (fmt == NULL) )
  86.         return -1;

  87.     va_start(argp, fmt);
  88.     while(*fmt != 0)
  89.     {
  90.         if (*fmt == ' ')
  91.         {
  92.             fmt ++;
  93.         }
  94.         else if (*fmt == '%')
  95.         {
  96.             len = fmt[1] ;
  97.             type = fmt[2];
  98.             if ( type != 'x' )
  99.                 return -1;
  100.             switch(len)
  101.             {
  102.             case '1':
  103.                 p = va_arg(argp, void *);
  104.                 *(INT8U *)(p) = *(INT8U *)buf++;
  105.                 break;
  106.             case '2':
  107.                 p = va_arg(argp, void *);
  108.                 *(INT16U *)(p) = *(INT16U *)buf;
  109.                 buf += 2;
  110.                 break;
  111.             case '4':
  112.                 p = va_arg(argp, void *);
  113.                 *(INT32U *)(p) = *(INT32U *)buf;
  114.                 buf += 4;
  115.                 break;
  116.             default:
  117.                 return -1;
  118.                 break;
  119.             }
  120.             fmt += 3;
  121.         }        
  122.         else
  123.         {            
  124.             fmt += 2;
  125.             buf ++;
  126.         }        
  127.     }
  128.     va_end(argp);
  129.     return 0;
  130. }

  131. void main( void )
  132. {
  133.    INT8U buf[20];
  134.    INT8U a = 1;
  135.    INT32U b = 2;
  136.    INT32U c1;
  137.    INT8U c2;
  138.    INT8U c3;
  139.    bprintf(buf, "12 34 56 78 %1x %1x 55", a, b);
  140.    bscan(buf, "%4x %1x %1x", &c1, &c2, &c3);
  141. }

阅读(3001) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~