我正在读一本书,它定义了一个函数来替换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',所以我们无法在下一次迭代中找到它?
我在这里缺少什么?
答案 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'