zoukankan      html  css  js  c++  java
  • sscanf,scanf,fscanf与正则表达式(转帖)

    表头文件 #include(stdio.h )

    定义函数 int sscanf (const char *str,const char * format,........);
    函数说明 sscanf()会将参数str的字符串根据参数format字符串来转换并格式化数据。格式转换形式请参考scanf()。转换后的结果存于对应的参数内。
    返回值 成功则返回参数数目,失败则返回-1,错误原因存于errno中。

    # include < stdio. h>
    int main( )
    {
          const char * s = "iios/12DDWDFF@122" ;
          char buf[ 20] ;
          sscanf ( s, "%*[^/]/%[^@]" , buf ) ;
          printf ( "%s\n" , buf ) ;
          return 0;
    }
    结果为: 12DDWDFF
    sscanf与scanf类似,都是用于输入的,只是后者以屏幕( stdin ) 为输入源,前者以固定字符串为输入源。

    函数原型:
    int scanf( const char *format [,argument]... );
    其中的format可以是一个或多个 {%[*] [width] [{h | l | I64 | L}]type | ' ' | '\t' | '\n' | 非%符号},
    注:{a|b|c}表示a,b,c中选一,[d],表示可以有d也可以没有d。
    宽度,一般可以忽略,用法如:
    const char sourceStr[] = "hello, world";
    char buf[10] = {0};
    sscanf(sourceStr, "%5s", buf); //%5s,只取5个字符
    cout << buf<< endl;
    结果为:hello
    {h | l | I64 | L}:参数的size,通常h表示单字节size,I表示2字节 size,L表示4字节size(double例外),l64表示8字节size。
    type :这就很多了,就是%s,%d之类。

    特别的:
    %*[width] [{h | l | I64 | L}]type 表示满足该条件的被过滤掉,不会向目标参数中写入值。如:
    const char sourceStr[] = "hello, world";
    char buf[10] = {0};
    sscanf(sourceStr, "%*s%s", buf); //%*s表示第一个匹配到的%s被过滤掉,即hello被过滤了
    cout << buf<< endl;
    结果为:world

    支持集合操作:
    %[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)
    %[aB'] 匹配a、B、'中一员,贪婪性
    %[^a] 匹配非a的任意字符,贪婪性

    1. 常见用法。

    以下是引用片段:
      charstr[ 512] = { 0} ;
      sscanf( "123456" , "%s" , str) ;
      printf( "str=%s" , str) ;

    2. 取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。

    以下是引用片段:
      sscanf( "123456" , "%4s" , str) ;
      printf( "str=%s" , str) ;

    3. 取到指定字符为止的字符串。如在下例中,取遇到空格为止字符串。

    以下是引用片段:
      sscanf( "123456abcdedf" , "%[^]" , str) ;
      printf( "str=%s" , str) ;

    4. 取仅包含指定字符集的字符串。如在下例中,取仅包含1到9和小写字母的字符串。

    以下是引用片段:
      sscanf( "123456abcdedfBCDEF" , "%[1-9a-z]" , str) ;
      printf( "str=%s" , str) ;

    5. 取到指定字符集为止的字符串。如在下例中,取遇到大写字母为止的字符串。

    以下是引用片段:
      sscanf( "123456abcdedfBCDEF" , "%[^A-Z]" , str) ;
      printf( "str=%s" , str) ;

    搜集一些特殊用法:

    % [ ] 的用法:% [ ] 表示要读入一个字符集合, 如果[ 后面第一个字符是”^”,则表示反意思。[ ] 内的字符串可以是1或更多字符组成。空字符集(% [ ] )是违反规定的,可导致不可预知的结果。% [ ^ ] 也是违反规定的。
    % [ a- z] 读取在 a- z 之间的字符串,如果不在此之前则停止,如
    char s[ ] = "hello, my friend” ; // 注意: ,逗号在不 a-z之间
    sscanf( s, “%[a-z]”, string ) ; // string=hello

    %[^a-z] 读取不在 a-z 之间的字符串,如果碰到a-z之间的字符则停止,如
    char s[]=" HELLOkitty” ; // 注意: ,逗号在不 a-z之间
    sscanf ( s, “% [ ^ a- z] ”, string ) ; // string=HELLO

    % * [ ^ = ] 前面带 * 号表示不保存变量。跳过符合条件的字符串。
    char s[ ] = "notepad=1.0.0.1001" ;
    char szfilename [ 32] = "" ;
    int i = sscanf ( s, "%*[^=]" , szfilename ) ;
    // szfilename=NULL,因为没保存
    int i = sscanf ( s, "%*[^=]=%s" , szfilename ) ;
    // szfilename=1.0.0.1001

    % 40c 读取40个字符

    % [ ^ = ] 读取字符串直到碰到’= ’号,’^’后面可以带更多字符, 如:
    char s[ ] = "notepad=1.0.0.1001" ;
    char szfilename [ 32] = "" ;
    int i = sscanf ( s, "%[^=]" , szfilename ) ;
    // szfilename=notepad
    如果参数格式是:% [ ^ = : ] ,那么也可以从 notepad: 1. 0. 0. 1001读取notepad

    应用实例:Rinex星历数据读入
    以下是Rinex星历数据的片断:
    2 10 1 16 2 0 0.0 2.159508876503D-04 4.320099833421D-12 0.000000000000D+00
        9.500000000000D+01 1.165625000000D+01 5.293791936254D-09-3.076667279839D+00
        7.841736078262D-07 9.284008061513D-03 4.578381776810D-06 5.153754629135D+03
        5.256000000000D+05-1.527369022369D-07 1.733543031426D+00 1.303851604462D-08
        9.397921470752D-01 2.780625000000D+02 2.941268779788D+00-8.269273019842D-09
        1.892935991239D-10 1.000000000000D+00 1.566000000000D+03 0.000000000000D+00
        2.000000000000D+00 0.000000000000D+00-1.722946763039D-08 9.500000000000D+01
        5.184000000000D+05
    观察可以发现,有的数据连在了一起,没有空格分隔,如第二行5.293791936254D-09-3.076667279839D+00。这时应该如何提取出相应的数据呢?代码如下:

    #include <stdafx.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int _tmain(int argc, _TCHAR* argv[])
    {
     int wn,year,month,day,hour,prn,minute;
     float second;
     char t1[30],t2[30],t3[30],t4[30],t5[30],temp[10];
     double f1,f2,f3,f4,d1,d2,d3,d4;
     FILE *RinexEPP_file;
      if ((RinexEPP_file = fopen("e:\data.txt", "rt")) == NULL) {
        fprintf(stderr, "Cannot open input file.\n");
        exit(1); }
     rewind(RinexEPP_file);
     if(fscanf(RinexEPP_file,"%d %d %d %d %d %d\n",
             &prn,&year,&month,&day,
             &hour,&minute)==EOF) return 1;
     fscanf(RinexEPP_file,"%4f",&second);
     fscanf(RinexEPP_file,"%[^D]",t1);  //读到D字符为止
     fscanf(RinexEPP_file,"%4s",temp);  //截取D后面的四个字符
     strcat(t1,temp);                   //将D前后两段相连
     d1=atof(t1);
     d2=atof(t2);
     d3=atof(t3);
     d4=atof(t4);
    }
    将其整理成一个函数如下:
    char *myscanf(FILE *RinexEPP_file);
    
    char *myscanf(FILE *RinexEPP_file)
    {
     char t1[30],temp[10];
     fscanf(RinexEPP_file,"%[^D]",t1);  //一直读到为D字符为止
     fscanf(RinexEPP_file,"%4s",temp);
     strcat(t1,temp);
     return t1;
    }
  • 相关阅读:
    MySQL锁总结
    DDL和DML
    字节、字、位、比特之间的关系
    Mysql数据库、表设计规范指南
    Mysql性能优化关键配置指南
    3.python正则匹配不到内容时消耗大量内存
    1. postman使用
    2. python提示:TypeError: unhashable type: 'list'
    14. selenium的Page Object模型
    12.unittest的学习
  • 原文地址:https://www.cnblogs.com/mazhenyu/p/1735179.html
Copyright © 2011-2022 走看看