有人可以让我知道问题所在以及如何纠正。
该函数需要从包含' '
,'\t'
和'\n'
的字符串中删除所有空格。函数的输出应该是输入字符串的副本,但所有字符串都是删除了空格。函数原型应保持不变void
。
void removeWS(char *strNoSpace, const char *strWithSpace)
{
int i, j;
stringNoSpace = malloc(strlen(strWithSpace) + 1);
for(i = 0, j = 0; stringWithSpace[i] != '\0'; i++, j++){
if (isspace((char) strWithSpace[i]) != 0){
strNoSpace[j++] = strWithSpace[i];
}
}
}
答案 0 :(得分:2)
简化到实际问题:
void removeWS(char *strNoSpace, const char *strWithSpace)
{
strNoSpace = malloc(strlen(strWithSpace) + 1);
// ...
}
// ....
char* paramStrNoSpace = NULL;
char* paramStrWithSpace = "...";
removeWS(paramStrNoSpace, paramStrWithSpace);
现在strNoSpace
是paramStrNoSpace
的副本它指向相同的内存,在本例中为NULL。然后在您的函数内部,您将strNoSpace
更改为某个内容,malloc()
返回。现在strNoSpace
与NULL不同,而paramStrNoSpace
仍为NULL,因为strNoSpace
是该指针的副本。
一个简单的解决办法可能是将指针传递给指针:
void removeWS(char **strNoSpace, const char *strWithSpace)
{
*strNoSpace = malloc(strlen(strWithSpace) + 1);
// ...
}
// ....
char* paramStrNoSpace = NULL;
char* paramStrWithSpace = "...";
removeWS(¶mStrNoSpace, paramStrWithSpace);
现在strNoSpace
指向存储指针paramStrNoSpace
的确切位置。每当您修改*strNoSpace
时,您实际上都会立即修改paramStrNoSpace
。
这种方法的缺点是,当函数只分配并返回新内存时,迟早会忘记内存分配。经验法则是:谁分配内存,也有责任释放它。因此,我认为更好的接口会期望调用者为此函数分配足够的内存:
void removeWS(char *strNoSpace, ind strNoSpaceMaxSize, const char *strWithSpace)
{
// ...
}
// ....
char* paramStrWithSpace = "...";
char* paramStrNoSpace = malloc(strlen(paramStrWithSpace) + 1);
removeWS(paramStrNoSpace, strlen(paramStrWithSpace), paramStrWithSpace);
现在removeWS()
永远不会改变strWithSpace
。因此我们可以再次将它作为一个简单的指针传递,但我们必须告诉removeWS()
分配的内存块的大小。它必须在运行时检查并停止以防万一没有足够的内存。
答案 1 :(得分:1)
我看到三个明显的问题:
string
条件中引用for
,而不是strWithSpace
NUL
('\0'
)个终结符,但是当你完成循环时却没有,所以如果输入没有以空格结尾,那么字符串就不会被NUL
终止。j
,但也在for
循环增量步骤中推进它,因此您将离开NUL
s散落(过早地终止字符串)并在此之前跳过非空格字符。答案 2 :(得分:1)
这可以在删除字符时就地完成。指针to
和from
通过字符串前进。找到空格时,只会from
前进。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
void removeWS( char *strWithSpace)
{
//declare two pointers and set them to first character of strWithSpace
char *to = strWithSpace;
char *from = strWithSpace;
while ( *from) {//when from points to terminating '\0' while will exit
if ( isspace ( *from)) {
from++;//found space character, advance from
continue;//back to top of while
}
*to = *from;//copy from character to to
to++;//advance to
from++;//advance from
}
*to = '\0';//set terminating '\0'
}
int main( int argc, char *argv[])
{
char text[40] = {"text with spaces between the words"};
printf("before %s\n", text);
removeWS( text);
printf("after %s\n", text);
return 0;
}