c - 从字符数组中删除某些元素
问题描述
我有一个函数可以从给定的字符串中去除标点符号,并使其所有内容都小写:
void stripPunctuators(char *str)
{
int i, j, len = strlen(str);
for (i = 0; i < len; i++)
{
if (!isalpha(str[i]))
{
for (j = i; j < len; j++)
{
str[j] = str[j + 1];
}
len--;
}
str[i] = tolower(str[i]);
}
}
但是由于某种原因,当我连续有两个非字母字符时它会遇到麻烦......这是我的主要功能:
int main(void)
{
char str[50] = "Hello.";
printf("Before strip: %s\n", str);
stripPunctuators(str);
printf("After strip: %s\n", str);
char str2[50] = "Hello.!";
printf("Before strip: %s\n", str2);
stripPunctuators(str2);
printf("After strip: %s\n", str2);
return 0;
}
最后,这是我的输出:
Before strip: Hello.
After strip: hello
Before strip: Hello.!
After strip: hello!
谢谢你的帮助!
解决方案
考虑一个短字符串可能会有所帮助,例如a!@b
. 0..3
由于您使用了循环,您的索引变量将遍历包含在内的值for
。现在按照顺序:
0123 <- indexes
----
a!@b starting point, index = 0
a!@b index 0 was a, no shift, set index to 1
a@b index 1 was !, shift, set index to 2 ***
a@b index 2 was b, no shift, set index to 3, exit loop
从那里,您应该能够看到移动字符串的其余部分并增加索引将导致下一个字符被跳过(请参阅***
标记以了解出错的地方)。
您可以通过使用一个循环来解决此问题,在该循环中,当您进行轮班时,索引不会while
增加(可能使用而不是for
一个好主意)。这样,无增量的移位将使您重新检查相同的索引,即下一个字符(由于移位)。
但是,每次要删除字符时都对字符串余数进行完全移位是相当低效的,因为您很可能需要再次更改这些字符。
最好使用带有(伪代码)之类的源和目标指针:
set src and dst to address of first character
while character at src is not end-of-string:
if character at src is not punctuation:
set character at dst to be character at src
increment dst
increment src
set character at dst to be end-of-string
而且,如果你想在 C 中使用它,它会是:
void stripPunctuators(char *str) {
char *src = str;
char *dst = str;
while (*src != '\0') {
if (isalpha(*src)) {
*dst = *src; // or combine:
dst++; // "*dst++ = *src"
}
src++;
}
*dst = '\0';
}
请注意,我
isalpha
在我的代码中使用它只是因为那是您在原始代码中使用的那个。由于这将剥离标点符号(例如数字),因此您可能需要重新检查它是否适合使用。该isalnum
功能可能更合适,但也取决于您的用例。您可能还需要保留空格。否则事情可能会变得非常混乱和难以阅读:-)
推荐阅读
- c++ - std::vector emplace_back 和 push_back 是线程安全的吗
- ios - 删除列表 UICollectionView 单元格分隔符
- python - 通过python中的列循环总结几列
- php - 我帐户中的 Woocommerce 订单查看页面显示 404 未找到
- flutter - 我在图像上添加了 Watermaek,但图像未加载
- typescript - 在 Vue 打字稿中使用 i18n
- image-manipulation - CodeIgniter 4 图像处理错误 withFile() null
- eloquent - Eloquent 如何使用 (NOT) EXISTS 和选择子查询
- at-command - GSM/GPRS 板 sim800c "AT+CTTS=?" 返回“错误”
- python - 具有多个输入的 TensorFlow 生成器读取多个文件会导致内核崩溃