处理空格的就地字符串处理函数的实现
by 沈东良 http://blog.csdn.net/shendl
本文介绍处理空格的就地字符串处理函数的实现。就是在字符串内存内进行的字符串操作。不涉及到分配新的内存。
把字符串尾部的空格去掉的函数:
char * cstring_trimTail(char *str){ if(str==NULL){ return NULL; } unsigned int i=0; for(;str[i]!='\0';i++){ ; } //i==length; for(i--;i>=0 && isspace(str[i]);i--){ str[i]='\0'; } return str; }
去掉字符串尾部的空格是最简单的。因为字符串是以'\0'表示字符串的终止的。因此,只需要把尾部的第一个空格找到,然后设置为‘\0’就可以了。
把字符串开头的空格去掉的函数:
char * cstring_trimHead(char *str){ if(str==NULL){ return NULL; } unsigned int i=0; for(;isspace(str[i]);i++){ ; } //i==first unspace char unsigned int newIndex=0; for(;str[i]!='\0';i++,newIndex++){ str[newIndex]=str[i]; } //i==strlen for(;newIndex<i;newIndex++){ str[newIndex]='\0'; } return str; }
把字符串头部的空格去掉,需要移动后面每一个字符串。这个新的字符串的大小<=原来的字符串。因此可以寄生在原来的字符串的内存空间中。
newIndex表示新字符串的尾部。它的头部是0。这样就可以把头部的空格都去除了。并且在O(n)算法复杂度内解决这个问题。
char * cstring_trim(char *str){ if(str==NULL){ return NULL; } str=cstring_trimTail(str); str=cstring_trimHead(str); return str; }
把超过一个连续空格合并为一个空格的字符串处理函数:
int
cstring_exactMoreSpace(char* str) {
inti = 0;
intnewStrNextIndex = 0;
for(i = 0; str[i] != '\0';i++) {
if(
isspace(str[i])
){
if(newStrNextIndex!=i){
str[newStrNextIndex]= str[i];
}
newStrNextIndex++;
printf("firstspace,str[%d]:%c\n",i, str[i]);
for(i++;
isspace(str[i])
;i++) {
printf("Ignorespace,str[%d]:%c\n",i, str[i]);
}
i--;
}else{
if(newStrNextIndex!=i){
str[newStrNextIndex]= str[i];
}
newStrNextIndex++;
}
}
str[newStrNextIndex]= '\0';
printf("%s\n",str);
return0;
}
把字符串中的连续空格合并为一个空格,需要创建一个新的字符串。这个新的字符串的大小<=原来的字符串。因此也可以寄生在原来的字符串的内存空间中。
newStrNextIndex表示新字符串的尾部。它的头部是0。当遇到空格,就在新字符串写入这个空格,并且扫描掉紧根在后面的空格。在O(n)算法复杂度内解决这个问题。
小结
这几个函数是就地字符串处理函数,节约了内存空间。
要注意,C中的常量字符串在常量区分配,该内存区域是只读的,如果试图修改该内存区域的数据,会引发段错误,进程崩溃。因此,它们的参数不能是常量字符串。
这些函数的核心算法思想是,构建一个新的字符串,这个字符串寄生在原来的字符串的内存空间中。
只要有了“构建新的字符串”的思路,就能够很容易地理解上述函数实现。