【问题标题】:How do I remove all occurrences of a specific char from a string?如何从字符串中删除所有出现的特定字符?
【发布时间】:2013-10-08 07:47:04
【问题描述】:

您好,我试图从 C 字符串中删除一个字符,但输出似乎不正确。例如,如果。 输入字符串 = “你好” 指定要删除的字符 = "l" 我的输出是“HeXXo”。删除字符后,我似乎需要将值推入?

代码如下:

#include <stdio.h>
#include <stdlib.h>

void squeeze(char str[], char c);

void main (){
  char input[100];
  char c;
  printf("Enter string \n");
  gets(input);
  printf("Enter char \n");
  scanf("%c", &c);
  printf("char is %c \n", c);
  squeeze(input , c );

  getchar();
  getchar();
  getchar();
}

void squeeze(char str[], char c){
    int count = 0, i = 0;   

    while (str[count] != '\0'){
      count++;
    }

    printf("Count = %d  \n", count);
    for ( i = 0 ; i != count; i++){
      if (str[i] == c){
            printf("Found at str[%d] \n", i);
            str[i] = "";
      }
    }
    printf(" String is = %s", str);
}

【问题讨论】:

  • 一些灵感——你可以在不分配额外缓冲区的情况下实现这个squeeze 函数。您迭代字符串,在其中维护两个指针:一个“读取位置”指针和一个“写入位置”指针。我不想破坏乐趣,但这可能会让你开始。
  • 哪个输出是正确的? “Heo”或“Helo”还是其他?
  • Freich 的提示一针见血,你应该注意它。本练习的目的是训练您使用两个独立的指针遍历数组序列,答案比您想象的要简单。请注意:gets() 是卑鄙和邪恶的,以至于它在当前标准中已被弃用,并且不会出现在下一个标准中。不要使用它。请改用fgets()。

标签: c string char


【解决方案1】:
str[i] = "";

您试图分配一个指针而不是一个字符。您可能指的是' ',但这也不是从字符串中删除字符的正确方法,而是替换它们。试试:

char *p = str;
for (i = 0 ; i != count; i++) {
    if (str[i] != c)
        *p++ = str[i];
}
*p = 0;

编辑

这是一个我更喜欢的解决方案:

char *p = s; /* p points to the most current "accepted" char. */
while (*s) {
    /* If we accept a char we store it and we advance p. */
    if (*s != ch)
        *p++ = *s;

    /* We always advance s. */
    s++;
}
/* We 0-terminate p. */
*p = 0;

【讨论】:

  • +1 这是唯一对手头的任务有意义的答案,坦率地说,我对每个空间重复移动相同数据的答案数量感到震惊遇到,分配空间缓冲区等。呃。我会使用两个指针,但那是次要的,这个正确答案的总体思路是相同的。
  • @WhozCraig 谢谢!我也喜欢 2 指针习语(没有 i),但我认为保留一些原始代码对 OP 更有帮助。
  • 我认为这可能是原因。
  • 如果您使用do-while 循环,您可以避免最后一个*p = 0 分配。
  • @FrerichRaabe 或将 for 中的测试条件更改为 i &lt;= count 任何一种方式都有效(假设字符串长度不在 int-overflow 的边界上,不太可能)。
【解决方案2】:
#include <stdio.h>
#include <stdlib.h>

void squeeze(char str[], char c);

int main ()
{
    char input[100];
    char c;
    printf("Enter string \n");
    gets(input);
    printf("Enter char \n");
    scanf("%c", &c);
    printf("char is %c \n", c);
    squeeze(input , c );

    return 0;
}

void squeeze(char str[], char c){
    int count = 0, i = 0,j=0;
    char str2[100];
    while (str[count] != '\0'){
        count++;}

    printf("Count = %d  \n", count);
    for ( i = 0,j=0 ; i != count; i++){
        if (str[i] == c)
        {
            printf("Found at str[%d] \n", i);
            //    str[i] = '';
        }
        else
        {
            str2[j]=str[i];
            j++ ;
        }
    }

    str2[j]='\0' ;
    printf(" String is = %s", str2);
}

这是您的代码的修改版本。我创建了一个新数组并将其余不匹配的字母放入其中。希望对您有所帮助。

【讨论】:

  • 现在考虑当出现超过 99 个字符的字符串时会发生什么。同样重要的是,原始字符串根本没有被修改,因此违背了函数的目的。
  • 是的。这是一个有效的点。但是您的输入数组(保存原始数据的字符串)的大小为 100。所以即使我们采用最坏的情况(即相同的字符串没有找到匹配和 100 个字符),函数中使用的 str2 不需要保存超过 100 个字符。
  • ...和空终止符?请注意,我提到了一个字符串 longer 大于 99(即 strlen() 报告 100 或更多)。
【解决方案3】:

有

str[i] = "";

您将字符串文字的地址分配给位于i 位置的char。首先,您应该得到编译器的警告,因为类型并不真正兼容;其次,您需要在那里分配一个替换字符,例如

str[i] = '_';

或实际上删除它们,方法是将所有后面的字符移回(从而覆盖要替换的字符)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-26
    • 2016-01-02
    • 2014-08-07
    • 1970-01-01
    • 2013-12-18
    • 1970-01-01
    • 2012-12-06
    相关资源
    最近更新 更多