【发布时间】:2020-12-04 16:58:44
【问题描述】:
我需要一个 C 函数,它接受一个前后可能有相同字符的字符串(分配在堆栈上,而不是堆上);我想剪掉那些字符。我可能不知道有多少页眉/页脚字符,也不一定总是知道有问题的字符是什么。
换句话说,如果我的原始字符串是:
xxxThis is a string.xxxx
……那我想要……
This is a string.
返回。理想情况下,我喜欢这样的解决方案:
char str1[50] = “xxxThis is a string.xxxx”;
str1 = trimString( str1 );
printf(“Returned string is:: %s\n”, str1); // prints “This is a string.”
这是我的代码:
char* trimString( char* str1, char x ){
int i = 0;
int j = (int)strlen( str1 ) - 1;
printf("string is :: >>%s<<\n", str1);
while( str1[i] == x ){
i++;
}
while( str1[j] == x ){
j--;
}
str1 = strncpy( str1, str1+i, (j-i) );
return str1;
}
int main(){
char str1[50] = "xxxThis is a string.xxxx";
str1[25] = '\0';
printf("%s\n", trimString( str1, 'x' ) );
printf("END OF PROGRAM.\n");
return 0;
}
这是输出:
This is a stringing.xxxx
END OF PROGRAM.
有两个明显的问题。首先,我认为我正确地删除了“x”字符,但是当我将修剪后的字符串复制回“str1”变量时,我只用新字符串覆盖了旧字符串的前 n 个字符。原字符串的残骸还在。
更严重的是,我还没有接近像这样调用这个函数的目标:
str1 = trimString( str1, ‘x’ );
我可以这样调用我的函数:
char tmpStr[50] = trimString( str1, ‘x’ );
memcpy( str1, tmpStr );
但这很痛苦,现在我不得不担心临时字符串的大小。另外,我想我得打电话给trimString()很多很多很多次,所以如果我用一行代码就可以了,而且不用担心管理临时字符串等,那就太好了。
有什么建议或意见吗?
【问题讨论】:
-
trim()函数需要添加一个空终止符。 -
你不能像这样使用
strncpy()。源字符串和目标字符串不允许重叠。请改用memmove()。 -
“分配在堆栈上,而不是堆上”是一个实现细节。为什么会有这样的要求?
标签: c char trim c-strings function-definition