【原创】sscanf函数的超级用法 分类: Linux --- C 2015-07-23 18:20 10人阅读 评论(0) 收藏

【原创】sscanf函数的超级用法

今天接到一个任务,读取指定格式的配置文件信息,以备后续之用。
配置文件server.conf格式如下:

  name:course
   version:course.2015.07.23
    [monitor_model]   :   1
         [course_count]  :3   

    [course_stat1]   :  ON
   [course_name1]  :  server
    [course_path1] : /usr/bin/

[course_stat2]:ON    
[course_name2]:CameraV2  
   [course_path2]    :/usr/bin/

[course_stat3   ]  :ON
  [  course_name3]   :IpCamera
[course_path3]:/usr/bin/

其实配置文件格式没有这么乱,之所以这么乱是为了展示sscanf函数的强大按格式读取的能力。正常的配置文件应该比较整齐,例如这样:

name:course
version:course.2015.07.23
[monitor_model]:1
[course_count]:3

[course_stat1]:ON
[course_name1]:server
[course_path1]:/usr/bin/

[course_stat2]:ON
[course_name2]:CameraV2
[course_path2]:/usr/bin/

[course_stat3]:ON
[course_name3]:IpCamera
[course_path3]:/usr/bin/

处理程序代码:

/*************************************************************************
    > File Name: read_conf_server.c
    > Author: Geng
    > Mail: genglut@163.com
    > Created Time: Thu 23 Jul 2015 06:26:32 PM CST
 ************************************************************************/
//声明;函数l_trim、r_trim、a_trim是借来的,资源共享嘛

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>

#define KEYVALLEN 128

/*   删除字符串左边的空格   */
char * l_trim( char * szOutput, const char *szInput )
{
    assert( szInput != NULL );
    assert( szOutput != NULL );
    assert( szOutput != szInput );
    for ( NULL; *szInput != '\0' && isspace( *szInput ); ++szInput )
    {
        ;
    }
    return(strcpy( szOutput, szInput ) );
}


/*   删除字符串右边的空格   */
char *r_trim( char *szOutput, const char *szInput )
{
    char *p = NULL;
    assert( szInput != NULL );
    assert( szOutput != NULL );
    assert( szOutput != szInput );
    strcpy( szOutput, szInput );
    for ( p = szOutput + strlen( szOutput ) - 1; p >= szOutput && isspace( *p ); --p )
    {
        ;
    }
    *(++p) = '\0';
    return(szOutput);
}


/*   删除字符串两边的空格   */
char * a_trim( char * szOutput, const char * szInput )
{
    char *p = NULL;
    assert( szInput != NULL );
    assert( szOutput != NULL );
    l_trim( szOutput, szInput );
    for ( p = szOutput + strlen( szOutput ) - 1; p >= szOutput && isspace( *p ); --p )
    {
        ;
    }
    *(++p) = '\0';
    return(szOutput);
}


int GetProfileString( char *profile )
{
    char    temp[32],temp1[32],temp2[32];
    char    *buf;
    char    buf_i[KEYVALLEN], buf_o[KEYVALLEN];
    FILE    *fp;
    if ( (fp = fopen( profile, "r" ) ) == NULL )
    {
        printf( "openfile [%s] error [%s]\n", profile, strerror( errno ) );
        return(-1);
    }
    fseek( fp, 0, SEEK_SET );

    while ( !feof( fp ) && fgets( buf_i, KEYVALLEN, fp ) != NULL )
    {
        /*
        KEYVALLEN为128,从配置文件可以看到,fgets每次读的内容为一行。
        读过一行之后,用a_trim处理掉改行两遍的空格和tab缩进。
        */
        a_trim( buf_o, buf_i );
        if ( strlen( buf_o ) <= 0 )
            continue;
        buf = NULL;
        buf = buf_o;
        if ( buf[0] != '[' )
        {
            continue;
        }
        else
        {
            /*
            该句为代码的核心部分,其具体含义可参考sscanf的用法。
            */
            sscanf( buf, "%*[^A-Za-z]%[^] ]%*[^:]:%s", temp1,temp2);
            printf("%s=%s\n",temp1,temp2);
            continue;
        }
    }
    fclose( fp );
}


void main()
{
    GetProfileString( "./server.conf");
}

运行结果:

$ ./a.out 
monitor_model=1
course_count=3
course_stat1=ON
course_name1=server
course_path1=/usr/bin/
course_stat2=ON
course_name2=CameraV2
course_path2=/usr/bin/
course_stat3=ON
course_name3=IpCamera
course_path3=/usr/bin/

写在最后:
从运行结果可以看出,程序已经完美解决问题。说是sscanf的超级用法一点都不过~
函数中代码可以再精简一些,要下班了,go~

sscanf函数其他使用方法可参考
http://blog.csdn.net/gzshun/article/details/7081736
http://www.91linux.com/html/article/program/cpp/20081130/14121.html

原文链接:
http://blog.csdn.net/geng823/article/details/47026405

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2015-07-23 18:20  GengLUT  阅读(142)  评论(0编辑  收藏  举报