【问题标题】:How to remove the character at a given index from a string in C?如何从C中的字符串中删除给定索引处的字符?
【发布时间】:2011-03-28 10:25:20
【问题描述】:

如何从字符串中删除一个字符?

如果我有字符串 "abcdef" 并且我想删除 "b" 我该怎么做?

使用以下代码可以轻松删除 first 字符:

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

int main()
{
   char word[] = "abcdef";
   char word2[10];

   strcpy(word2,&word[1]);

   printf("%s\n", word2);

   return 0;
}

和

strncpy(word2,word,strlen(word)-1);

会给我没有 last 字符的字符串,但我仍然不知道如何删除字符串中间中的字符。

【问题讨论】:

标签: c string


【解决方案1】:

memmove 可以处理重叠区域,我会尝试类似的方法(未测试,可能是 +-1 问题)

char word[] = "abcdef";  
int idxToDel = 2; 
memmove(&word[idxToDel], &word[idxToDel + 1], strlen(word) - idxToDel);

之前:"abcdef"

之后:"abdef"

【讨论】:

    【解决方案2】:

    试试这个:

    void removeChar(char *str, char garbage) {
    
        char *src, *dst;
        for (src = dst = str; *src != '\0'; src++) {
            *dst = *src;
            if (*dst != garbage) dst++;
        }
        *dst = '\0';
    }
    

    测试程序:

    int main(void) {
        char* str = malloc(strlen("abcdef")+1);
        strcpy(str, "abcdef");
        removeChar(str, 'b');
        printf("%s", str);
        free(str);
        return 0;
    }
    

    结果:

    >>acdef
    

    【讨论】:

    • 不知道要移除的角色位置的时候最好!
    • 既然这段代码已经假设字符存在,为什么不直接使用 for(dst = str; *dst !=garbage; dst++){} *dst = '\0';跨度>
    【解决方案3】:

    我删除所有指定字符的方法:

    void RemoveChars(char *s, char c)
    {
        int writer = 0, reader = 0;
    
        while (s[reader])
        {
            if (s[reader]!=c) 
            {   
                s[writer++] = s[reader];
            }
    
            reader++;       
        }
    
        s[writer]=0;
    }
    

    【讨论】:

    • 赞成良好的结构和变量名称,能够比上面的简洁变体更容易地遵循此代码。谢谢
    • 很好的解决方案!我只会投票给像removeAllCharOccurrences这样的函数名称。
    【解决方案4】:

    真的很惊讶以前没有发布过。

    strcpy(&str[idx_to_delete], &str[idx_to_delete + 1]);
    

    相当高效和简单。 strcpy 在大多数实现中使用 memmove。

    【讨论】:

    • 这是未定义的行为。正如 C99 的第 7.21.2.3 节(“strcpy 函数”)所解释的,“如果复制发生在重叠的对象之间,则行为是未定义的。”至于使用memmove“在大多数实现中” - [需要引用]。
    【解决方案5】:
    char a[]="string";
    int toBeRemoved=2;
    memmove(&a[toBeRemoved],&a[toBeRemoved+1],strlen(a)-toBeRemoved);
    puts(a);
    

    试试这个。 memmove 将与它重叠。 经过测试。

    【讨论】:

      【解决方案6】:
      int chartoremove = 1;
      
      strncpy(word2, word, chartoremove);
      strncpy(((char*)word2)+chartoremove, ((char*)word)+chartoremove+1,
          strlen(word)-1-chartoremove);
      

      丑到爆

      【讨论】:

        【解决方案7】:

        下面将通过从第一个字符串参数中删除第二个字符串参数中出现的任何字符来稍微扩展问题。

        /*
         * delete one character from a string
         */
        static void
        _strdelchr( char *s, size_t i, size_t *a, size_t *b)
        {
          size_t        j;
        
          if( *a == *b)
            *a = i - 1;
          else
            for( j = *b + 1; j < i; j++)
              s[++(*a)] = s[j];
          *b = i;
        }
        
        /*
         * delete all occurrences of characters in search from s
         * returns nr. of deleted characters
         */
        size_t
        strdelstr( char *s, const char *search)
        { 
          size_t        l               = strlen(s);
          size_t        n               = strlen(search);
          size_t        i;
          size_t        a               = 0;
          size_t        b               = 0;
        
          for( i = 0; i < l; i++)
            if( memchr( search, s[i], n))
              _strdelchr( s, i, &a, &b);
          _strdelchr( s, l, &a, &b);
          s[++a] = '\0';
          return l - a;
        }
        

        【讨论】:

          【解决方案8】:
          #include <stdio.h>
          #include <string.h>
          
          int main(){
              char ch[15],ch1[15];
              int i;
              gets(ch);  // the original string
              for (i=0;i<strlen(ch);i++){  
                  while (ch[i]==ch[i+1]){ 
                      strncpy(ch1,ch,i+1); //ch1 contains all the characters up to and including x
                      ch1[i]='\0'; //removing x from ch1
                      strcpy(ch,&ch[i+1]);  //(shrinking ch) removing all the characters up to and including x from ch
                      strcat(ch1,ch); //rejoining both parts
                      strcpy(ch,ch1); //just wanna stay classy
                  }
              }
              puts(ch);
          }
          

          假设 x 是您要删除的字符的“符号” ,我的想法是将字符串分成两部分:

          第一部分将计算从索引 0 到(包括)目标字符 x 的所有字符。

          第二部分计算x之后的所有字符(不包括x)

          现在您所要做的就是重新加入这两个部分。

          【讨论】:

            【解决方案9】:

            使用strcat() 连接字符串。

            但strcat() 不允许重叠,因此您需要创建一个新字符串来保存输出。

            【讨论】:

              【解决方案10】:

              我尝试使用strncpy() 和snprintf()。

              int ridx = 1;  
              strncpy(word2,word,ridx);   
              snprintf(word2+ridx,10-ridx,"%s",&word[ridx+1]);
              

              【讨论】:

                【解决方案11】:

                另一种解决方案,使用 memmove() 以及 index() 和 sizeof():

                char buf[100] = "abcdef";
                char remove = 'b';
                
                char* c;
                if ((c = index(buf, remove)) != NULL) {
                    size_t len_left = sizeof(buf) - (c+1-buf);
                    memmove(c, c+1, len_left);
                }
                

                buf[] 现在包含“acdef”

                【讨论】:

                  【解决方案12】:

                  如果您通过索引,这可能是最快的之一:

                  void removeChar(char *str, unsigned int index) {
                      char *src;
                      for (src = str+index; *src != '\0'; *src = *(src+1),++src) ;
                      *src = '\0';
                  }
                  

                  【讨论】:

                    【解决方案13】:

                    此代码将删除您从字符串中输入的所有字符

                    #include <stdio.h>
                    #include <string.h>
                    
                    #define SIZE 1000
                    
                    char *erase_c(char *p, int ch)
                    {
                        char *ptr;
                    
                        while (ptr = strchr(p, ch))
                            strcpy(ptr, ptr + 1);
                    
                        return p;
                    }
                    
                    int main()
                    {
                        char str[SIZE];
                        int ch;
                    
                        printf("Enter a string\n");
                        gets(str);
                        printf("Enter the character to delete\n");
                        ch = getchar();
                    
                        erase_c(str, ch);
                    
                        puts(str);
                    
                        return 0;
                    }
                    

                    输入

                    a man, a plan, a canal Panama
                    

                    输出

                     A mn,  pln,  cnl, Pnm!
                    

                    【讨论】:

                    • 从不,从不,从不使用gets,由于缓冲区溢出漏洞,它已从 C11 中完全删除。你应该改用fgets (str, SIZE, stdin)。
                    【解决方案14】:

                    编辑:根据库的最新版本更新了代码zstring_remove_chr()。

                    来自 BSD 许可的 C 字符串处理库,名为 zString

                    https://github.com/fnoyanisi/zString

                    删除字符的函数

                    int zstring_search_chr(char *token,char s){
                        if (!token || s=='\0')
                            return 0;
                    
                        for (;*token; token++)
                            if (*token == s)
                                return 1;
                    
                        return 0;
                    }
                    
                    char *zstring_remove_chr(char *str,const char *bad) {
                        char *src = str , *dst = str;
                    
                        /* validate input */
                        if (!(str && bad))
                            return NULL;
                    
                        while(*src)
                            if(zstring_search_chr(bad,*src))
                                src++;
                            else
                                *dst++ = *src++;  /* assign first, then incement */
                    
                        *dst='\0';
                        return str;
                    }
                    

                    示例用法

                       char s[]="this is a trial string to test the function.";
                       char *d=" .";
                       printf("%s\n",zstring_remove_chr(s,d));
                    

                    示例输出

                      thisisatrialstringtotestthefunction
                    

                    【讨论】:

                      【解决方案15】:
                      #include <stdio.h>
                      #include <stdlib.h>
                      #include <string.h>
                      #define MAX 50
                      void dele_char(char s[],char ch)
                      {
                          int i,j;
                      
                          for(i=0;s[i]!='\0';i++)
                          {
                              if(s[i]==ch)
                              {
                                  for(j=i;s[j]!='\0';j++)
                                  s[j]=s[j+1];
                                  i--;
                              }
                          }
                      }
                      
                      int main()
                      {
                          char s[MAX],ch;
                          printf("Enter the string\n");
                          gets(s);
                          printf("Enter The char to be deleted\n");
                          scanf("%c",&ch);
                          dele_char(s,ch);
                          printf("After Deletion:= %s\n",s);
                          return 0;
                      }
                      

                      【讨论】:

                      • 简单,希望对您有所帮助
                      【解决方案16】:

                      这是您可能正在寻找的,而 counter 是索引。

                      #include <stdio.h>
                      
                      int main(){
                      
                          char str[20];
                          int i,counter;
                          gets(str);
                          scanf("%d", &counter);
                      
                          for (i= counter+1; str[i]!='\0'; i++){
                              str[i-1]=str[i];
                          }
                          str[i-1]=0;
                          puts(str);
                      
                      
                      
                          return 0;
                      }
                      

                      【讨论】:

                        【解决方案17】:

                        我知道这个问题很老了,但我将把我的实现留在这里:

                        char    *ft_strdelchr(const char *str,char c)
                        {
                                int   i;
                                int   j;
                                char  *s;
                                char  *newstr;
                        
                                i = 0;
                                j = 0;
                                // cast to char* to be able to modify, bc the param is const
                                // you guys can remove this and change the param too
                                s = (char*)str;
                                // malloc the new string with the necessary length. 
                                // obs: strcountchr returns int number of c(haracters) inside s(tring)
                                if (!(newstr = malloc(ft_strlen(s) - ft_strcountchr(s, c) + 1 * sizeof(char))))
                                        return (NULL);
                                while (s[i])
                                {
                                        if (s[i] != c)
                                        {
                                                newstr[j] = s[i];
                                                j++;
                                        }
                                        i++;
                                }
                                return (newstr);
                        }
                        

                        只需将不等于您要删除的字符的字符扔到一个新字符串中。

                        【讨论】:

                          【解决方案18】:

                          以下应该这样做:

                          #include <stdio.h>
                          #include <string.h>
                          
                          int main (int argc, char const* argv[])
                          {
                              char word[] = "abcde";
                              int i;
                              int len = strlen(word);
                              int rem = 1;
                          
                              /* remove rem'th char from word */
                              for (i = rem; i < len - 1; i++) word[i] = word[i + 1];
                              if (i < len) word[i] = '\0';
                          
                              printf("%s\n", word);
                              return 0;
                          }
                          

                          【讨论】:

                            【解决方案19】:

                            这是一种非常基本的方法:

                            void remove_character(char *string, int index) {
                               for (index; *(string + index) != '\0'; index++) {
                                  *(string + index) = *(string + index + 1);
                               }
                            }
                            

                            【讨论】:

                              【解决方案20】:

                              摆脱\0的一种方便、简单和快速的方法是在strncpy而不是strcpy的帮助下复制没有最后一个字符(\0)的字符串:

                              strncpy(newStrg,oldStrg,(strlen(oldStrg)-1));
                              

                              【讨论】:

                                猜你喜欢
                                • 1970-01-01
                                • 2011-12-08
                                • 2021-12-15
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                相关资源
                                最近更新 更多