簡體   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