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

来源:互联网 发布:手机知乎怎么发表文章 编辑:程序博客网 时间:2024/04/29 18:25
        很多时候软件用到解析一个文本的场合,比如解析一个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) ;   //方向是从左向右,把左边的参数按照格式存储到右边的变量中。