在C语言中分割字符串
2010-10-11 15:26
267 查看
C语言的库函数中,没有类似java中String类的split方法,可以把一个长字符串分割为字符串数组。不过,还是可以利用几个库函数,自己造出split的效果。虽然不像java那样支持分隔符为正则表达式,但一般情况下也够用了。
这个split函数原型是:int split(char ***words, const char *line, char delim);
为什么第一个参数是指向字符串数组的指针(char ***),而不是字符串数组(char **)呢?因为在C语言中,函数中的参数其实是它实际传入参数的副本。如果调用split时仅仅把字符串数组传入,在split函数中,实际上是对其副本执行malloc操作,而其正本并未有任何改变,没有分配到新的内存,导致程序执行时崩溃。
而使用指向字符串数组的指针就不一样了。split函数会在其副本所指向的内存上进行malloc操作,也就是在其正本所指向的内存上进行malloc操作,子函数中所作的改变在调用它的函数中得以体现。
林锐的《高质量C++/C编程指南》一书中,7.4节,《指针参数是如何传递内存的?》,对此问题有详细的解释:编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是_p,编译器使_p = p。如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。这就是指针可以用作输出参数的原因。……,(但如果)_p申请了新的内存,只是把_p所指的内存地址改变了,但是p丝毫未变。
此外,本案例的另一个值得注意的地方,是执行strncpy()之后,应当及时在新的字符串的末尾置结束符,否则会出现奇怪的字符串溢出错误,不要以为strncpy()之前的memset()能够解决这一问题。
本案例的测试结果如下图:
#include <stdio.h> #include <stdlib.h> #include <string.h> /* * count the number of a character in a string */ int count_char(const char *str, char c) { int count = 0; char *p = str; while ( *p ) { if ( *p == c ) count++; p++; } return count; } /* * split a string into words, must free after use */ int split(char ***words, const char *line, char delim) { int word_counter = count_char(line, delim) + 1; *words = (char **) malloc(sizeof(char *) * word_counter); int i = 0; char *p = line; while ( 1 ) { char *s = p; p = strchr(p, delim); int len = ( p ) ? p - s : strlen(s); (*words)[i] = (char *) malloc(sizeof(char) * (len + 1)); strncpy((*words)[i], s, len); (*words)[i][len] = 0; if ( !p ) break; p++; i++; } return word_counter; } /* * unit test */ int main(void) { char *line = "300;D;Event: /"460008103448843/",/"19/",/"2010/09/07-10-46-00.00/",/"/",/"/",/"/",/"0/",/"/",/"/",/"/",/"/",/"ROAMER MTC/",/"52/",/"Voice MTC/",/"460008103448843/",/"/",/"MO/",/"0011/",/"45500000103BD/",/"2010/09/07-10-46-52.00/",/"1/",/"/",/"8647145557^353070016806810/",/"11^^1^957^/",/"^^/",/"^^^/",/"45500000103BD/",/"MOSMTMSC/",/"/",/"/",/"/",/"/",/"rui_momsc1_mom1_1572_02933.dat/",/"1/",/"/""; printf("%s/n", line); char **words = NULL; int n = split(&words, line, ','); printf("split it into %d fields:/n", n); int i; for ( i = 0; i < n; i++) { printf("field %d: [%s]/n", i, words[i]); free(words[i]); } free(words); return 0; }
这个split函数原型是:int split(char ***words, const char *line, char delim);
为什么第一个参数是指向字符串数组的指针(char ***),而不是字符串数组(char **)呢?因为在C语言中,函数中的参数其实是它实际传入参数的副本。如果调用split时仅仅把字符串数组传入,在split函数中,实际上是对其副本执行malloc操作,而其正本并未有任何改变,没有分配到新的内存,导致程序执行时崩溃。
而使用指向字符串数组的指针就不一样了。split函数会在其副本所指向的内存上进行malloc操作,也就是在其正本所指向的内存上进行malloc操作,子函数中所作的改变在调用它的函数中得以体现。
林锐的《高质量C++/C编程指南》一书中,7.4节,《指针参数是如何传递内存的?》,对此问题有详细的解释:编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是_p,编译器使_p = p。如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。这就是指针可以用作输出参数的原因。……,(但如果)_p申请了新的内存,只是把_p所指的内存地址改变了,但是p丝毫未变。
此外,本案例的另一个值得注意的地方,是执行strncpy()之后,应当及时在新的字符串的末尾置结束符,否则会出现奇怪的字符串溢出错误,不要以为strncpy()之前的memset()能够解决这一问题。
本案例的测试结果如下图:
相关文章推荐
- 用C语言来分割字符串
- C语言比较巧妙的字符串分割程序
- C语言:使用strtok_s()函数简单分割字符串
- C语言中strtok函数进行分割字符串!
- c语言 字符串的拼接和分割
- C语言 对字符串进行分割
- 字符串分割函数——C语言
- C语言strtok()函数:字符串分割
- C语言 strtok 字符串分割
- C语言的字符串分割
- [C语言]字符串处理 - 以指定的字符串分割字符串(支持中文字符)
- C语言strtok()函数:字符串分割
- c语言实现字符串分割
- C语言分割字符串strtok函数
- C语言中计算字符串长度与分割字符串的方法
- hdu 2072 1106学一波字符串分割,C语言与C++两种方法
- C语言中自定义Split函数分割字符串以及利用strtol函数把字符串转换为数字的实例
- C++字符串分割和C语言常用格式控制
- c语言实现字符串分割
- C语言实现字符串分割(类似vb中split函数)