2013-12-08 32 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'