用C替换字符串中的字符

时间:2013-12-08 04:55:31

标签: c

我正在读一本书,它定义了一个函数来替换char数组中的字符,如下所示:

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++]);
}

我的问题是,想象一下,在remove []中我们有b而在str []中我们有“hi”,所以:

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

从我在代码中看到的,我们会这样做:

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

但是,这意味着,我们只是覆盖了'i',所以我们无法在下一次迭代中找到它?

我在这里缺少什么?

1 个答案:

答案 0 :(得分:0)

该代码中有一些明显的漏洞。第一种是使用可以签名或未签名的裸char数据类型。如果它已经签名,则当用作数组索引时,负值可能会导致严重问题。

第二个问题是检测角色是否被删除。您可以使用!removeArray[remove[src]]来尝试分析是否应删除源字符串中的字符。但这不是你应该检查的remove数组,而是src数组。

最后,假设char类型是8位宽,因此将有256个不同的值。如果您知道就可以了,但对于真正可移植的代码,您可以使用UCHAR_MAX中的limits.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'