2013-12-08 30 views
1

替換字符我正在讀一本書,它定義一個函數來替換字符數組像這樣的字符:字符串使用C

void RemoveChars(char remove[], char str[]) 
{ 
    int src, dst, removeArray[256]; 
    for (src=0; src < 256; src++) { 
    removeArray[src] = 0; 
    } 

    src = 0; 
    while (remove[src]) { 
    removeArray[remove[src]] = 1; 
    src++; 
    } 

    src = dst = 0; 
    do { 
    if (!removeArray[remove[src]]) { 
     str[dst++] = str[src]; 
    } 
    } while (str[src++]); 
} 

我的問題在這裏,可想而知,在刪除[]我們具有B-並且在str []中我們有「hi」,所以:

str[0] = 'h' and str[1] = 1

從我的代碼中看到的,我們會做:

str[1] = str[0] --> str[1] = 'h' 

但是,這意味着,我們只是重寫了「我」,所以我們不能夠找到它的下一次迭代權?

缺少什麼我在這裏?

+0

編輯抱歉。我錯過了它。 –

+0

'dst'總是'<= src',所以代碼永遠不會像'str [1] = str [0]'那樣評估。 – Mat

+0

該代碼仍然看起來不正確 - 我沒有看到尾隨的NUL在哪裏下移。 – cbmanica

回答

0

該代碼中有幾個明顯的缺陷。首先是使用可能有符號或無符號的裸體數據類型char。如果它被簽名,那麼當用作數組索引時,負值可能會導致嚴重的問題。

第二個問題是檢測字符是否被刪除。您使用!removeArray[remove[src]]來嘗試和分析是否應刪除源字符串中的字符。但它不是你應該檢查的remove陣列,而是src陣列。

最後,你假設char類型是8位寬,因此將有256個不同的值。這可能是好的,如果你知道這種情況,但對於真正便攜的代碼,你可以使用UCHAR_MAXlimits.h

所以一個更好的起點(含評論)將是:

void removeChars (unsigned char *remove, unsigned char *str) { 
    size_t src, dst; 
    unsigned char removeMap [UCHAR_MAX + 1]; 

    // Initial map is to preserve everything. 

    memset (removeMap, 0, sizeof (removeMap)); 

    // For each character to be removed, change its map entry. 

    while (*remove != '\0') { 
     removeMap [*remove] = 1; 
     remove++; 
    } 

    // Run two pointers through the array, source and destination. 

    src = dst = 0; 
    do { 
     // Only if character allowed to survive will it be transferred. 

     if (! removeMap [str [src]]) { 
      str [dst++] = str [src]; 
     } 

    // Finish when end of string transferred. 

    } while (str [src++]); 
} 

相結合,與一些測試代碼:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <limits.h> 

void removeChars (unsigned char *, unsigned char *); 

char *mystrdup (char *s) { 
    char *news = malloc (strlen (s) + 1); 
    if (news != NULL) 
     strcpy (news, s); 
    return news; 
} 

int main (int argc, char *argv[]) { 
    if (argc != 3) { 
     printf ("Usage: testprog <string> <characters-to-remove>\n"); 
     return 1; 
    } 

    char *string = mystrdup (argv[1]); 
    char *remove = mystrdup (argv[2]); 

    removeChars (remove, string); 

    printf ("Result is '%s'\n", string); 

    free (string); 
    free (remove); 

    return 0; 
} 

,並運行它:

testprog 'Pax is a really nice guy' Piul 

給你的預期產出:

Result is 'ax s a reay nce gy'