如何从C中的字符串中删除所有出现的给定字符?
我试图从C中的一个字符串中删除一个字符。我的代码中存在的问题是它从字符串中删除了字符的第一个实例,同时也删除了该字符串中的所有字符之后的所有内容。例如,去除“你好”打印“他”“L”而不是“HEO”如何从C中的字符串中删除所有出现的给定字符?
int i;
char str1[30] = "Hello", *ptr1, c = 'l';
ptr1 = str1;
for (i=0; i<strlen(str1); i++)
{
if (*ptr1 == c) *ptr1 = 0;
printf("%c\n", *ptr1);
ptr1++;
}
我需要使用指针,这和想保持尽可能简单,因为我是一个初学者在C. 由于
你可以这样说:
void remove_all_chars(char* str, char c) {
char *pr = str, *pw = str;
while (*pr) {
*pw = *pr++;
pw += (*pw != c);
}
*pw = '\0';
}
int main() {
char str[] = "llHello, world!ll";
remove_all_chars(str, 'l');
printf("'%s'\n", str);
return 0;
}
的想法是保持一个独立的读取和写入指针(pr
阅读和pw
写作),总是提前读出指针,推进写指针只有当它不指向给定的字符时。
谢谢你简单的回答和描述,解决了它。也感谢所有人的意见。 – boutrosc 2012-03-27 18:42:16
为什么http://melpon.org/wandbox/permlink/qZPdItEH7hjg4sl3导致分段错误? '* pw = * ptr ++;'和'* pw =(* ptr)++;' – Destructor 2016-04-27 15:10:06
@Destructor'* pw = * ptr ++'增加指针(正确),'(* ptr)++'增加字符(不正确)。 – dasblinkenlight 2016-04-27 15:21:15
C定义一个字符串作为“字符的连续序列通过终止并且包括第一空字符”
是的,但几乎不能解释问题的答案。 – 2014-01-22 02:00:56
只是改变
if (*ptr1 == c) *ptr1 = 0;
到
if (*ptr1 == c) continue;
为@ouah说,它打破了在第一个NULL字符..
这不是一个足够的解决办法。 – 2014-01-22 02:02:36
的问题是,当你遇到一个匹配c
的第一个字符,你插入一个空字符在那里。这意味着你基本上切断了字符串的其余部分。
您需要做的是在找到匹配的字符时,将下列字符移回到一个位置。然后,您需要在最后插入空字符,具体取决于您删除了多少个字符。
char str1[30] = "Hello", *prt1, c = 'l';
char str2[30], *prt2;
prt1 = str1;
prt2 = str2;
while(*prt1 != 0)
{
if(*prt1 != c)
{
*prt2 = *prt1;
prt2++;
}
prt1++;
}
*prt2 = '\0';
如果您删除的地方,你将不得不串一个地方休息,每次左移你删除一个角色的人物,这是不是很有效。最好的方法是让第二个数组采用过滤后的字符串。例如,你可以像这样改变你的代码。
int i;
char str1[30] = "Hello", *ptr1, c = 'l';
char str2[30] = {0}, *ptr2;
ptr1 = str1;
ptr2 = str2;
for (i=0; i<strlen(str1); i++)
{
if (*ptr1 != c) *ptr2++=*ptr1;
ptr1++;
}
printf("%s\n", str2);
除了你真的不应该在这样的循环条件下调用'strlen()',这是一个很好的答案。当然,这是一个从问题中的代码继承的错误,但... – 2014-01-22 01:59:13
@Jonathan Leffler,这个答案使一些基本的错误,防止它成为一个很好的答案。每次删除角色时,不必将字符串的剩余部分移到左侧。这意味着一个嵌套的循环,答案证明不是必需的。此外,无论是将字符从一个字符串复制到另一个字符串都没有区别,因为它们都是同一块RAM。事实上,使用第二个字符串可能效率更低,因为使用远距离内存块会导致缓存未命中。 – 2014-10-28 15:35:35
我知道这是一种重复的答案,但是这个代码是解决问题的函数版本。我认为,由于提问者是初学者,他可能从分解版本的问题中学到很多东西。
int del_x_char(char *p, int x)
{
char *q;
x=first_occurance(p, 'i')/*you can replace any character that you want delete with 'i'*/
q=p+x;
while(*q=*(q+1))
q++;
*q='\0';
return 0;
}
int first_occurance(char *q, char phar)
{
int i=0;
while(*q)
{
if(*q++==phar)
return i;
i++;
}
return -1;
}
提示:在删除过程中,您希望将其他字母向上移动以覆盖您删除的字母。 '* ptr1 = 0;'不是这样做的。 – 2012-03-27 18:18:49
您还正在使用for/loop来解决每个char的索引,但是您从不使用实际索引(i的值) – 2012-03-27 18:20:33
另一件需要记住的事情是,在CS中,字符串以null结尾。 – 2012-03-27 18:21:25