如何在C语言中从字符串中删除给定索引处的字符?

58

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

如果我有字符串"abcdef",我想要删除"b",我该怎么做呢?

使用以下代码可以轻松删除第一个字符:

#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);

使用 slice 方法可以让我得到一个去掉最后一个字符的字符串,但是我仍然不知道如何删除中间的字符。


给定字符的所有出现次数:https://dev59.com/VVHTa4cB1Zd3GeqPU9SX - Ciro Santilli OurBigBook.com
22个回答

0

当计数器是索引时,这可能是您正在寻找的内容。

#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;
}

gets(str); 绝不是任何人应该寻找的。 - chqrlie

0

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

#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!

1
永远、永远、永远不要使用 gets,由于缓冲区溢出的漏洞,它已经在 C11 中被完全删除。你应该使用 fgets (str, SIZE, stdin) 代替。 - David C. Rankin
strcpy(ptr, ptr + 1); 未定义行为 - chqrlie

0

这是一种相当基本的方法:

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

你应该首先检查 index <= strlen(string) 是否成立。 - chqrlie

0
另一种解决方案是使用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"


sizeof(buf) - (c+1-buf); 非常低效。 - chqrlie

0
使用strcat()函数来连接字符串。
但是strcat()函数不允许重叠,所以您需要创建一个新的字符串来保存输出。

0

我尝试使用strncpy()snprintf()

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

更简单的写法是:snprintf(word2, sizeof word2, "%.*s%s", (int)ridx, word, word + ridx + 1); - chqrlie

0
#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)。
现在,您只需要重新连接这两个部分即可。

0
#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;
}

很简单,希望有所帮助。 - Mushrif Ali

0

如果你传递索引,这可能是最快的之一:

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

0

我知道这个问题很老了,但是我会在这里留下我的实现:

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);
}

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


"... + 1 * sizeof(char)" 既冗余又不一致。 - chqrlie
s = (char*)str; 这一行是不必要的,应该将 s 定义为 const char *s 并移除强制类型转换。 - chqrlie
while 循环后缺少 newstr[j] = '\0'; - chqrlie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接