Benjamin

静以修身,俭以养德,非澹薄无以明志,非宁静无以致远。
随笔 - 386, 文章 - 0, 评论 - 196, 引用 - 0
数据加载中……

标准C---关于字符串操作

字符串操作是常用的操作之一,下面是相关的函数介绍和相关注意的地方,
一、
strtok查找函数,这个函数改变了源字符串,而且第一个参数必须是数组,不能是指针或字符串,如果是指针或字符串,则会报异常,直接返回NULL.如果不想改变源字符串的内容,建议用strstr来查找子串。
其他常用的查找函数有
strchrstrrchr,前者在字符在字符串第一次出现的位置,后者则是查询的是字符在字符串中出现的最后一次的位置;两个函数返回的都是地址,注意,这里返回的首地址的值就是这个字符。这两个查找函数都不会改变源字符串(数组的)内容。

二、Strlenmemset,如下面的代码:
char* temp = (char*)malloc(67 * sizeof(char));
Int leng = strlen(temp);
Memset(temp,0,strlen(temp));
Leng = strlen(temp);
两次leng的值是不一样的,第一次是正确的值,第二次是0strlen找的是’\0’,但是不包括’\0’;

三、strcpy等虽然不安全可,但是要记住:strcpy_s等是微软自己搞的一套,在liunx上是无法使用的。如果要部分拷贝,我们可以在
strcpy的参数上直接对地址加减或在strncpy上对源字符串的地址更改或是对strncpy上的第三个参数加以修改来达到目的。
strcpy等不安全主要表现在没有会发生字符串截断、   字符串没有正确的结束符,还有就是字符串的边界问题。
malloc和free一般情况下要配对,但是如果是static变量,则可以不用free,不会发生内存泄漏的情况。

四、构造字符串---sprintf,提取一个字符串的某个字段---scanf,这两个是相反的过程。
sprintf常用在拼接字符串,如:sprintf(buffer,"%s=%s","Three",3);buffer中的字符串就是"Three=3",有时它可以替代strcat函数;

sscanf和sprintf是两个相反的过程,如果你知道字符串的格式完全可以用这个函数还替代strtok和strstr这两个查找函数;例如:char str[] = "watch is 34.3433 !!!";
那么我们可以提取34.3433,sscanf(str,"%s %s %f",ch,&t_fTemp);这个t_fTemp的值就是34.3433.

五、提取子串和字符在字符串的位置:strstr、strtok、strchr等,这些函数有个缺憾:如果我们要查找字串“222”是否在“22222 tok“中时,这几个函数都不起作用,要么自己写,要么自己根据字串在父串中的指针的下个地址的内容来确定.例如:
char str[] = "2222 tok";
char end_char = ' ';//这个可由自己根据业务定义
if(*(strstr(str,"222")+1) != end_char)
{
..................
}
六、strstr函数另一个缺点:char str[] = "port 56 78" char *ch = strstr(str,"port");ch的值是str的首地址,而非我们要的结果,如果把空格改成/t/r等转义字符
结果依然如此,我们在使用str相关的函数时要主义类似的问题,这种结果在解析协议和读文件时是致命,而且是难以察觉的错误。

posted on 2010-07-28 21:10 Benjamin 阅读(720) 评论(6)  编辑 收藏 引用 所属分类: C/C++

评论

# re: 标准C---关于字符串操作  回复  更多评论   

但是如果是static变量,则可以不用free,不会发生内存泄漏的情况。

这个怎么理解??
2010-07-29 09:13 | egmkang

# re: 标准C---关于字符串操作  回复  更多评论   

_s,_t的那一套函数都是CRT函数,Unix-Like米有
如果嫌strcpy不安全,可以使用strncpy,带n的都有防止越界的功能.
2010-07-29 09:14 | egmkang

# re: 标准C---关于字符串操作  回复  更多评论   

如果是静态变量是malloc产生的,可以不用free,不会发生内存泄漏的情况;
所有str函数都有越界问题,都不是安全的;很多的编程规范也是禁止使用这些函数,在一些恶意代码就是通过这些函数的漏洞来注入的。
2010-07-29 13:40 | Benjamin

# re: 标准C---关于字符串操作  回复  更多评论   

char* temp = (char*)malloc(67 * sizeof(char));
Int leng = strlen(temp);
Memset(temp,0,strlen(temp));
Leng = strlen(temp);
两次leng的值是不一样的,第一次是正确的值,第二次是0;strlen找的是’\0’,但是不包括’\0’;

strlen遇‘\0’结束,所以,在未memset之前,分配的内存块都是随机值,有可能是0,第一次有可能不是固定的值
2010-07-29 16:55 | roy

# re: 标准C---关于字符串操作  回复  更多评论   

@roy

好像我有点过时了
刚才分别在Linux/Solaris/Tru64/HP-UX下测试这段代码N次,每次输出都是0

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

int main() {
char *tmp = (char *) malloc(1024 * sizeof(char));
printf("%d\n", strlen(tmp));
free(tmp);
return 0;
}

2010-07-29 17:11 | roy

# re: 标准C---关于字符串操作  回复  更多评论   

@roy
不错,第一次返回的值不是它本身的长度,是从分配的首地址开始起一直到找到结束符的长度,可能是0也可能是不是0.如果正好下一个地址存放的就是结束符,那么长度就恰巧为0,所以你上面的strlen返回0也正常。
2010-07-29 21:21 | Benjamin

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理