【问题标题】:how to remove a character from a string with loop?如何使用循环从字符串中删除字符?
【发布时间】:2018-12-17 17:43:26
【问题描述】:

我试图让程序从用户输入的字符串中删除一个字符,但在循环中出现错误。 (附带问题:在字符串中添加一个字符是否是“相同”的代码并进行了一些小改动?)

PS 编程新手...

【问题讨论】:

  • k < str 高度可疑
  • getchar() 的调用是为了什么?它会从每行输入中删除第一个字符,这似乎不太可能是您想要的
  • fgets 之前调用getchar 似乎是错误的。 if (str[k] != ch) 尝试将来自str 的字符与ch 中的第一个字符的地址进行比较。

标签: c string loops


【解决方案1】:

这是你想要达到的目标吗?

变化:

  • getchar() 和 fgets() 到 scanf()
  • 添加 strlen() 以获取字符串长度
  • 将输入字符串的长度添加到 printf
  • 添加零初始化字符串

注意:每次使用 scanf() 输入后,您必须按回车键。

int main()
{      
    char str[100] = { 0 };
    char ch[5] = { 0 };
    int k, j;

    printf("Write text:\n");
    scanf("%s", str);

    printf("Input was: %s\nLength: %d\n", str, strlen(str));

    printf("Write a character that should be removed\n");
    scanf("%s", ch);

    for (k = 0, j = 0; k < strlen(str); k++)
    {
        if (str[k] != ch[0]) {
            str[j] = str[k];
            j++;
        }
    }
    str[j] = '\0';
    printf("String after removing a character: %s", str);
}

【讨论】:

  • 他想要所有 5 通道。需要额外的循环。
  • 这是@fake-account的情况吗?
  • 建议将strlen 的结果保存在一个变量中并将其用作循环条件,而不是在循环的每次迭代中遍历字符串。
  • @JohanBregell 为例,如果用户写“hello”,然后选择要删除的字母“e”,结果应该是“hllo”。我也尝试过 strlen 但由于我试图避免它(出于学习原因)我想使用不同的方式但得到相同的结果。
  • 我上面写的代码就是这样做的。如果您不想使用 strlen(),则必须在 for 循环头中检查 str[k] != '\0'。
【解决方案2】:

你的代码有问题:

  1. str[k] != ch 将是一个有效的测试,如果 ch 确实是一个字符而不是长度为 5 的字符数组。这将比较 str[k] 的字符值与地址 &amp;ch[0] .

  2. 如果k 是在&amp;str[0] 初始化的char * 指针,而不是从0 开始的int 循环索引,则k &lt; str 将是一个有效的比较。

更正的代码:

int main(void) 
{
    char str[100];
    char ch[5];
    int k, j;

    printf("Write text:\n");
    //getchar();
    fgets(str, 100, stdin);

    printf("Input was: %s\n", str);

    printf("Write a character that should be removed\n");
    //getchar();
    fgets(ch, 5, stdin);

    for (k = 0, j = 0; k < strlen(str); k++)
    {
        if (str[k] != ch[0])
        {
            str[j] = str[k];
            j++;
        }
    }
    str[j] = '\0';
    printf("String after removing a character = %s", str);

    return 0;
}

【讨论】:

    【解决方案3】:

    这里有两个实现。两者都从字符串 str 中删除所有出现的字符 ch

    第一个算法要快得多。第二种比较慢但是容易理解

    #include <stdio.h>
    #include <string.h>
    

    char *removechar(char *str, int ch)
    {
        char *cptr = str, *readptr = str;
    
        while(*readptr)
        {
            if(*readptr == ch)
            {
                readptr++;
            }
            else
            {
                *cptr++ = *readptr++;
            }
        }
        *cptr = 0;
        return str;
    }
    

    char *removechar(char *str, int ch)
    {
        char *cpos = str;
    
        while((cpos = strchr(cpos, ch)))
        {
            strcpy(cpos, cpos + 1);
        }
        return str;
    }
    

    int main()
    {
        char s[] = "Hello World";
    
        printf("%s\n", removechar(s, 'd'));
        printf("%s\n", removechar(s, 'l'));
    
        return 0;
    }
    

    【讨论】:

      【解决方案4】:

      这是你想要达到的目标吗?

      #include<stdio.h>
      #include<stdlib.h>
      #include<string.h>
      
      int main(){
          char str[100],c;
          printf("Write text:\n");
          fgets(str,100,stdin);
          printf("Input was: %s\n", str);
          printf("Write a character that should be removed\n");
          c=getchar();
          for(int k=0;k<strlen(str);k++){
              if(str[k]==c){
                  for(int j=k;j<strlen(str);j++){
                      str[j]=str[j+1];
                  }
              }
          }
           printf("String after removing a character = %s", str);
           return 0;
      }
      

      【讨论】:

      • 非常糟糕的算法。
      • 你为什么这么认为?
      • 效率极低(复制整个扩孔字符串)+ 循环中对 strlen 的多次调用。非常非常糟糕。看看我的答案(这个用指针),看看有什么不同。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-04
      相关资源
      最近更新 更多