C语言解析文本的程序 && sscanf/sprintf

        很多时候软件用到解析一个文本的场合,比如解析一个TXT文件,将有用的数据读出来并进行处理;或者读一个流文件,找出对应的值取出来。实例如下,一个调试文本是如下格式:

// R, Gr, Gb, B per light source

    0F12 4819  //,16,0},
/* Clock0, System clock 58MHz, PVI clock 48Mhz, (Preview) */

     0F12 F000  //,16,0},
     P10

     0F12 FA05  //,16,0},

如上,文本构造是:寄存器地址跟Value为一组的序列组成,其中有注释行,还有以P开头的延时行。程序需要读出地址和数据和延时,用来在线调试某些器件。大致程序如下:

uint16  init_reg[4000] = {0};       //寄存器数组,假设有4000个寄存器要写入
uint16  init_val[4000] = {0};        //参数值数组

char* curr_ptr = NULL;              //字符流指针

char* buf ;                                    //BUF是打开文件后的内存首指针

curr_ptr = buf;                            //从文件头开始查找
 while (curr_ptr < (buf + file_size))                //文件未遍历完
 {
               while ((*curr_ptr == ' ') || (*curr_ptr == '\t'))        /* Skip the 每行开始的Space & TAB */
                          curr_ptr++;    

               if (((*curr_ptr) == '/') && ((*(curr_ptr + 1)) == '*'))
               {
                         while (!(((*curr_ptr) == '*') && ((*(curr_ptr + 1)) == '/')))
                         {
                                 curr_ptr++;                                             /* Skip block comment code. */
                         }

                         while (!((*curr_ptr == 0x0D) && (*(curr_ptr+1) == 0x0A)))        //换行
                             {
                                 curr_ptr++;
                         }

                         curr_ptr += 2;      /* Skip the enter line */
   
                         continue ;                              //开始下一行的查找
                  }
  
               if (((*curr_ptr) == '/') && (*(curr_ptr + 1) == '/') )  /* Comment line, skip it. */
               {
                         while (!((*curr_ptr == 0x0D) && (*(curr_ptr+1) == 0x0A)))
                        {
                                    curr_ptr++;
                        }

                        curr_ptr += 2;      /* Skip the enter line */

                        continue ;                  //开始下一行的查找
                 }
              /* This just content one enter line. */
              if (((*curr_ptr) == 0x0D) && ((*(curr_ptr + 1)) == 0x0A))        //调过单独的空行
                {
                        curr_ptr += 2;
                        continue ;
              }

              if ('P' == *curr_ptr)           //DELAY碰到延迟时间
                 {
                        init_reg[i] = 0xFCFC;              //延时寄存器
                            curr_ptr++;
                        init_val[i] = simple_strtol(curr_ptr, NULL, 10);             //以十进制把字符串转成数据赋给init_val[i] 
               }
               else
               {
                        init_reg[i] = simple_strtol(curr_ptr, NULL, 16);             //以十六进制把字符串转成地址赋给init_reg[i]
                        curr_ptr += 4;                          //跳过4个十六进制数的地址
                            char c;
                        do{
                                   c = *curr_ptr;
                                   if (('0' <= (c) && (c) <= '9')  || ('a' <= (c) && (c) <= 'f')  || ('A' <= (c) && (c) <= 'F'))
                                   {
                                             break;            //跳过无效字符,直到碰到参数值
                                         } 
                                   curr_ptr++;
                        }while(1);
                        init_val[i] = simple_strtol(curr_ptr, NULL, 16);          //以十六进制把字符串转成参数赋给init_val[i] 
               }
               i++;          //准备下一行待写的数据

                 /* Skip to next line directly. */
               while (!((*curr_ptr == 0x0D) && (*(curr_ptr+1) == 0x0A)))
               { 
                         curr_ptr++;
               }
               curr_ptr += 2;            //转下一行
 } 

        遍历完就可以从init_reg和init_val获得要写入的地址和参数。
===================================================================================================================

       sscanf/sprintf的典型用法:

sprintf (&szBuffer[strlen(szBuffer)], " [%d, %s]", (int)ui32Line, pszFileName); //方向是从右向左,把右边的参数按照格式存储到左边字符串变量中。

sscanf(regBuf, "%2s",  temp) ;
sscanf(temp, "%0x",  &RegAddr) ;   //方向是从左向右,把左边的参数按照格式存储到右边的变量中。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: null 是一个计算机科学术语,表示空值或缺失值。在编程语言中,null 通常用于表示一个变量没有被分配任何值。null 可以作为特殊值使用,例如表示函数没有返回任何值,或表示一个指针不指向任何有效的内存地址。 ### 回答2: &num);这段代码的作用是将字符串"7B"转换为十进制数并存储在变量num中。 首先,声明一个字符数组str,并将字符串"7B"赋值给它。之后,声明一个整型变量num,用于存储转换后的十进制数。 接下来,使用sscanf函数将字符串str按照八进制格式"%o"进行转换,并将转换结果存储在num变量的地址中。"%o"是用于转换八进制数的格式控制说明符。 最终,变量num中储存的值为转换后的十进制数,即十进制数123。 需要注意的是,这里的字符串"7B"表示的是一个八进制数,不是十进制数7乘以十进制数11。所以将其转换为十进制数时使用的是八进制的表示方式。 ### 回答3: &num); 这段代码的作用是将字符串"7B"解析为一个八进制数,并将解析后的结果赋值给变量num。其中"%o"是sscanf函数的格式控制字符串,表示将字符串按照八进制数的格式进行解析。 首先,变量str是一个字符数组,存储了字符串"7B"。字符数组的名称str可以被视为指针,指向存储该字符串的内存地址。 接下来,调用sscanf函数,它的第一个参数是待解析的字符串的地址,这里是str。第二个参数是格式控制字符串"%o",表示按照八进制数的格式解析字符串。第三个参数是一个指针,用于接收解析后的值,这里是&num,表示将解析后的八进制数赋值给变量num。 sscanf函数会根据格式控制字符串的要求,从待解析字符串中按照指定的格式提取数据,并将解析后的结果保存到给定的变量中。在这个例子中,待解析字符串是"7B",使用了"%o"格式控制字符串,意味着解析的结果是一个八进制数。 最后,解析出来的八进制数会被赋值给变量num,供后续代码使用。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值