繁体   English   中英

用C语言从字符数组中去除空格

[英]Removing whitespace from a character array in C language

有人可以让我知道问题出在哪里以及如何纠正它。

该函数需要从包含' ''\\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];

        }

    }

}

剥离到实际问题:

void removeWS(char *strNoSpace, const char *strWithSpace)
{
    strNoSpace = malloc(strlen(strWithSpace) + 1);
    // ...
}

// ....
char* paramStrNoSpace = NULL;
char* paramStrWithSpace = "...";
removeWS(paramStrNoSpace, paramStrWithSpace);

现在strNoSpaceparamStrNoSpace的副本,它指向同一个内存,在本例中为 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(&paramStrNoSpace, 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. 您在for条件中引用string ,而不是strWithSpace
  2. 当您看到空格时,您只会放置NUL ( '\\0' ) 终止符(这实际上毫无意义,因为您将覆盖下一个非空格字符),但不会在您完成循环时放置,因此如果输入不以空格结尾,字符串不是以NUL结尾的。
  3. 您在循环中正确推进(或不正确) j ,但也在for循环增量步骤中推进它,因此您将NUL分散在周围(过早终止字符串)并在此之前跳过非空格字符。

这可以在删除字符时就地完成。 指针tofrom提前通过字符串。 当找到一个空间时,只有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;
}

尝试这个

void removeWS(char *strNoSpace, const char *strWithSpace)
{
    int i, j;

    strNoSpace = malloc(strlen(strWithSpace) + 1);
    if ( strNoSpace == NULL ) {
            // error handle 
    }

    for(i = 0, j = 0; strWithSpace[i] != '\0'; i++ ) {    
        if ( isspace( strWithSpace[ i ] ) == 0 ) {
                strNoSpace[j++] = strWithSpace[i];    
        }    
    }
    strNoSpace[ j ] = '\0';
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM