C语言 字符串处理技巧(sscanf、strstr等用法)
2016-03-01 15:22
609 查看
之前有项目需要对日志进行大量提取和分析操作,除正则表达式这一强大的工具外,若是来不及学习正则表达式,又迫切地需要提取字符串。可以利用C语言自带的几个字符串处理函数来搞定。但必须注意符号、空格和换行符的细节问题。
sscanf的用法
int sscanf(const char *buffer,const char *format,[argument ]...);
根据format定义的形式,截取符合该形式的值,格式化输出到之后的传入的参数中。
sscanf支持正则,功能丰富,但必须注意的是:匹配条件比较苛刻,一旦未获取到参数极易引起段错误。一定要注意传入的必须是地址。
错误例子:
char * test = "ABCDE10FG\n";
int num = 0;
sscanf(test,"ABCDEF%dFG",num);
printf("num is %d\n",num);
程序结果:
写入位置 0x00000000 时发生访问冲突
一定要注意sscanf传入的必须是地址。
正确用法:
char * test = "ABCDE10FG\n";
int num = 0;
sscanf(test,"ABCDEF%dFG",&num);
printf("num is %d\n",num);
sscanf截取字符串
除截取数字比较方便外,sscanf也可截图字符串中的字符,但用法上有需要注意:
简单的%s输出格式化字符串不好用。
举例:
char * test = "ABCDE10FG\n";
int num = 0;
char target[4];
sscanf(test,"ABCDEF%d%sG",%num,target);
printf("num is :%d,targetis :%s\n",num,target);
我们期待target的值是”F“,
但实际上的输出是:”FG\n“,因为sscanf遇到%s的时候,直接将后边的所有字符串赋给了char,不会截取其中的内容,而且除了截取的内容与期望不符外,
如果字符串赋值越界,则直接引起栈错误。
错误例子:
char * test = "ABCDE10FG\n";
int num = 0;
char target[1];
sscanf(test,"ABCDEF%d%sG",%num,target);
printf("num is :%d,target is :%s\n",num,target);
输出结果
Run-Time Check Failure #2 - Stack around the variable 'target' was corrupted.
因为%s的格式化输出为3个字符,赋值给字符数组造成越界。
必须指定字符串的数量才能用sscanf截取。
正确例子:
char * test = "ABCDE10FG\n";
int num = 0;
char target[1];
sscanf(test,"ABCDEF%d%1sG",%num,target);
printf("num is :%d,targetis :%s\n",num,target);
输出结果:
num is :10,targe0t is :F
这种指定数量才能格式化输出用起来比较不方便,比如截取序列号等位数不一定怎么办?
strstr的用法
char *strstr(const char
*str1, const char *str2);
搜索一个字符串在另一个字符串中的第一次出现。该函数返回字符串的其余部分.
举例:
const char *test = "ABC_DEF_EFG";
char *target = strstr(test,"_");
target中保存的字符串是”_DEF_EFG“
可用两次strstr截取关键字之间的字符串。
举例:
const char * test = "ABC_DEF_EFG";
char *flag_1 = NULL;
flag_1 = strstr(test,"_");//获取第一个下划线的地址
if ( NULL != flag_1 )
{
flag_2 =NULL;
flag_2 = strstr(flag_1+1,"_");//获取第二个下划线的地址
}
if(flag_2 == NULL)
return ;
char * target = (char *)malloc(flag_2 - flag_1 - 1);
strncpy(target , flag_1+1 , (flag_2-flag_1 -1))//获取下划线之间的内容
结果:target的内容为”DEF“
一个实现读取文本关键字的简单流程:
fopen->fseek->fgets->fclose
sprintf (buf_com, "%s\\manipulate.log\\iolog_iostat",LogPath);
fp = fopen(buf_com,"r");
if(fp == NULL)
{
return ERROR_NOT_OPEN_FILE;
}
fseek(fp,searchlen,SEEK_SET);
while(fgets(readbuf,1024,fp))
{
tmppoint = head;
dmpoint = strstr(readbuf,"dm-");
if(dmpoint)
{
int dm_num=0;
sscanf(dmpoint,"dm-%d",&dm_num);
printf("dm_num is %d",dm_num);
}
}
fclose(fp);
本人博客园文章搬运
sscanf的用法
int sscanf(const char *buffer,const char *format,[argument ]...);
根据format定义的形式,截取符合该形式的值,格式化输出到之后的传入的参数中。
sscanf支持正则,功能丰富,但必须注意的是:匹配条件比较苛刻,一旦未获取到参数极易引起段错误。一定要注意传入的必须是地址。
错误例子:
char * test = "ABCDE10FG\n";
int num = 0;
sscanf(test,"ABCDEF%dFG",num);
printf("num is %d\n",num);
程序结果:
写入位置 0x00000000 时发生访问冲突
一定要注意sscanf传入的必须是地址。
正确用法:
char * test = "ABCDE10FG\n";
int num = 0;
sscanf(test,"ABCDEF%dFG",&num);
printf("num is %d\n",num);
sscanf截取字符串
除截取数字比较方便外,sscanf也可截图字符串中的字符,但用法上有需要注意:
简单的%s输出格式化字符串不好用。
举例:
char * test = "ABCDE10FG\n";
int num = 0;
char target[4];
sscanf(test,"ABCDEF%d%sG",%num,target);
printf("num is :%d,targetis :%s\n",num,target);
我们期待target的值是”F“,
但实际上的输出是:”FG\n“,因为sscanf遇到%s的时候,直接将后边的所有字符串赋给了char,不会截取其中的内容,而且除了截取的内容与期望不符外,
如果字符串赋值越界,则直接引起栈错误。
错误例子:
char * test = "ABCDE10FG\n";
int num = 0;
char target[1];
sscanf(test,"ABCDEF%d%sG",%num,target);
printf("num is :%d,target is :%s\n",num,target);
输出结果
Run-Time Check Failure #2 - Stack around the variable 'target' was corrupted.
因为%s的格式化输出为3个字符,赋值给字符数组造成越界。
必须指定字符串的数量才能用sscanf截取。
正确例子:
char * test = "ABCDE10FG\n";
int num = 0;
char target[1];
sscanf(test,"ABCDEF%d%1sG",%num,target);
printf("num is :%d,targetis :%s\n",num,target);
输出结果:
num is :10,targe0t is :F
这种指定数量才能格式化输出用起来比较不方便,比如截取序列号等位数不一定怎么办?
strstr的用法
char *strstr(const char
*str1, const char *str2);
搜索一个字符串在另一个字符串中的第一次出现。该函数返回字符串的其余部分.
举例:
const char *test = "ABC_DEF_EFG";
char *target = strstr(test,"_");
target中保存的字符串是”_DEF_EFG“
可用两次strstr截取关键字之间的字符串。
举例:
const char * test = "ABC_DEF_EFG";
char *flag_1 = NULL;
flag_1 = strstr(test,"_");//获取第一个下划线的地址
if ( NULL != flag_1 )
{
flag_2 =NULL;
flag_2 = strstr(flag_1+1,"_");//获取第二个下划线的地址
}
if(flag_2 == NULL)
return ;
char * target = (char *)malloc(flag_2 - flag_1 - 1);
strncpy(target , flag_1+1 , (flag_2-flag_1 -1))//获取下划线之间的内容
结果:target的内容为”DEF“
一个实现读取文本关键字的简单流程:
fopen->fseek->fgets->fclose
sprintf (buf_com, "%s\\manipulate.log\\iolog_iostat",LogPath);
fp = fopen(buf_com,"r");
if(fp == NULL)
{
return ERROR_NOT_OPEN_FILE;
}
fseek(fp,searchlen,SEEK_SET);
while(fgets(readbuf,1024,fp))
{
tmppoint = head;
dmpoint = strstr(readbuf,"dm-");
if(dmpoint)
{
int dm_num=0;
sscanf(dmpoint,"dm-%d",&dm_num);
printf("dm_num is %d",dm_num);
}
}
fclose(fp);
本人博客园文章搬运
相关文章推荐
- C语言——位操作
- C语言发展简介
- 0.1欢迎来到C语言的世界(教程介绍)
- C++发展简介
- C++中的Vector的用法
- 图像验证码识别(八)——字符归一化
- C语言:华氏温度与摄氏温度对照表
- 图像验证码识别(七)——字符分割
- 将C语言编译成DLL并用C#进行调用以及关于从C#传输中文路径到C的DLL中打开文件的问题
- C++ 类中特殊成员变量(常量、静态、引用)的初始化方法
- 九度-简单题 题目1431:Sort
- C++中虚函数工作原理和(虚)继承类的内存占用大小计算
- hbase thrift C++ 简单测试
- 九度-简单题 题目1018:统计同成绩学生人数
- c语言实现不定参数调用
- C语言特点_01
- 20160215.CCPP体系详解(0025天)
- 20160216.CCPP体系详解(0026天)
- 20160215.CCPP体系详解(0025天)
- 20160216.CCPP体系详解(0026天)