全部博文(395)
分类: C/C++
2011-05-17 21:36:25
1. 字符串操作函数
程序按功能划分可分为数值运算、符号处理和I/O操作三类,符号处理程序占相当大的比例,符号处理程序无处不在,编译器、浏览器、Office套件等程序的主要功能都是符号处理。无论多复杂的符号处理都是由各种基本的字符串操作组成的,本节介绍如何用C语言的库函数做字符串初始化、取长度、拷贝、连接、比较、搜索等基本操作。
1.1. 初始化字符串
#include
void *memset(void *s, int c, size_t n);
返回值:s指向哪,返回的指针就指向哪memset 函数把s 所指的内存地址开始的n 个字节都填充为c 的值。通常c 的值为0,把一块内存区清零。例如定义char buf[10]; ,如果它是全局变量或静态变量,则自动初始化为0(位于.bss 段),如果它是函数的局部变量,则初值不确定,可以用memset(buf, 0, 10) 清零,由malloc 分配的内存初值也是不确定的,也可以用memset 清零。
1.2. 取字符串的长度
#include
size_t strlen(const char *s);
返回值:字符串的长度strlen 函数返回s 所指的字符串的长度。该函数从s 所指的第一个字符开始找'\0' 字符,一旦找到就返回,返回的长度不包括'\0' 字符在内。例如定义char buf[] = "hello"; ,则strlen(buf) 的值是5,但要注意,如果定义char buf[5] = "hello"; ,则调用strlen(buf) 是危险的,会造成数组访问越界。
1.3. 拷贝字符串
1.4. 连接字符串
#include
char *strcat(char *dest, const char *src);
char *strncat(char *dest, const char *src, size_t n);
返回值:dest指向哪,返回的指针就指向哪strcat 把src 所指的字符串连接到dest 所指的字符串后面,例如:
char d[10] = "foo";
char s[10] = "bar";
strcat(d, s);
printf("%s %s\n", d, s);调用strcat 函数后,缓冲区s 的内容没变,缓冲区d 中保存着字符串"foobar" ,注意原来"foo" 后面的'\0' 被连接上来的字符串"bar" 覆盖掉了,"bar" 后面的'\0' 仍保留。
strcat 和strcpy 有同样的问题,调用者必须确保dest 缓冲区足够大,否则会导致缓冲区溢出错误。strncat 函数通过参数n 指定一个长度,就可以避免缓冲区溢出错误。注意这个参数n 的含义和strncpy 的参数n 不同,它并不是缓冲区dest 的长度,而是表示最多从src 缓冲区中取n 个字符(不包括结尾的'\0' )连接到dest 后面。如果src 中前n 个字符没有出现'\0' ,则取前n 个字符再加一个'\0' 连接到dest 后面,所以strncat 总是保证dest 缓冲区以'\0' 结尾,这一点又和strncpy 不同,strncpy 并不保证dest 缓冲区以'\0' 结尾。所以,提供给strncat 函数的dest 缓冲区的大小至少应该是strlen(dest)+n+1 个字节,才能保证不溢出。
1.5. 比较字符串
#include
int memcmp(const void *s1, const void *s2, size_t n);
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
返回值:负值表示s1小于s2,0表示s1等于s2,正值表示s1大于s2memcmp 从前到后逐个比较缓冲区s1 和s2 的前n 个字节(不管里面有没有'\0' ),如果s1 和s2 的前n 个字节全都一样就返回0,如果遇到不一样的字节,s1 的字节比s2 小就返回负值,s1 的字节比s2 大就返回正值。
strcmp 把s1 和s2 当字符串比较,在其中一个字符串中遇到'\0' 时结束,按照上面的比较准则,"ABC" 比"abc" 小,"ABCD" 比"ABC" 大,"123A9" 比"123B2" 小。
strncmp 的比较结束条件是:要么在其中一个字符串中遇到'\0' 结束(类似于strcmp ),要么比较完n 个字符结束(类似于memcmp )。例如,strncmp("ABCD", "ABC", 3) 的返回值是0,strncmp("ABCD", "ABC", 4) 的返回值是正值。
#include
int strcasecmp(const char *s1, const char *s2);
int strncasecmp(const char *s1, const char *s2, size_t n);
返回值:负值表示s1小于s2,0表示s1等于s2,正值表示s1大于s2这两个函数和strcmp /strncmp 类似,但在比较过程中忽略大小写,大写字母A和小写字母a认为是相等的。这两个函数不属于C标准库,是POSIX标准中定义的。
1.6. 搜索字符串
#include
char *strchr(const char *s, int c);
char *strrchr(const char *s, int c);
返回值:如果找到字符c,返回字符串s中指向字符c的指针,如果找不到就返回NULLstrchr 在字符串s 中从前到后查找字符c ,找到字符c 第一次出现的位置时就返回,返回值指向这个位置,如果找不到字符c 就返回NULL 。strrchr 和strchr 类似,但是从右向左找字符c ,找到字符c 第一次出现的位置就返回,函数名中间多了一个字母r可以理解为Reverse。
#include
char *strstr(const char *haystack, const char *needle);
返回值:如果找到子串,返回值指向子串的开头,如果找不到就返回NULLstrstr 在一个长字符串中从前到后找一个子串(Substring),找到子串第一次出现的位置就返回,返回值指向子串的开头,如果找不到就返回NULL。这两个参数名很形象,在干草堆haystack 中找一根针needle ,按中文的说法叫大海捞针,显然haystack 是长字符串,needle 是要找的子串。
搜索子串有一个显而易见的算法,可以用两层的循环,外层循环把haystack 中的每一个字符的位置依次假定为子串的开头,内层循环从这个位置开始逐个比较haystack 和needle 的每个字符是否相同。想想这个算法最多需要做多少次比较?其实有比这个算法高效得多的算法,有兴趣的读者可以参考[算法导论 ]
转:http://blog.csdn.net/psophia/archive/2010/11/05/5988857.aspx
2.一个比较牛的函数: