簡體   English   中英

如何從C中的字符串中刪除給定索引處的字符?

[英]How to remove the character at a given index from a string in C?

如何從字符串中刪除一個字符?

如果我有字符串"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);

會給我沒有最后一個字符的字符串,但我仍然不知道如何刪除字符串中間的字符。

memmove可以處理重疊區域,我會嘗試類似的方法(未經測試,可能是 +-1 問題)

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

之前: "abcdef"

之后: "abdef"

嘗試這個 :

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

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

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;
}
char a[]="string";
int toBeRemoved=2;
memmove(&a[toBeRemoved],&a[toBeRemoved+1],strlen(a)-toBeRemoved);
puts(a);

嘗試這個 。 memmove將重疊它。 經測試。

真的很驚訝這個以前沒有發布過。

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

相當高效和簡單。 strcpy在大多數實現中使用memmove

int chartoremove = 1;

strncpy(word2, word, chartoremove);
strncpy(((char*)word2)+chartoremove, ((char*)word)+chartoremove+1,
    strlen(word)-1-chartoremove);

丑得要命

下面將通過從第一個字符串參數中刪除第二個字符串參數中出現的任何字符來擴展問題。

/*
 * 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;
}

這是從字符串中刪除元音的示例

 #include <stdio.h>
    #include <string.h>
    
    void lower_str_and_remove_vowel(int sz, char str[])
    {   
        for(int i = 0; i < sz; i++)
        {
            str[i] = tolower(str[i]);
            if(str[i] == 'a' || str[i] == 'e' || str[i] == 'i' || str[i] == 'o' || str[i] == 'u')
            {
                for(int j = i; j < sz; j++)
                {
                    str[j] = str[j + 1];
                }
                sz--;
                i--;
            }
        }
    }
    
    int main(void)
    {
        char str[101];
        gets(str);
        int sz = strlen(str);// size of string
        lower_str_and_remove_vowel(sz, str);
        puts(str);       
    }

輸入:

tour

輸出:

tr

另一種解決方案,使用 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”

編輯:根據庫的最新版本更新了代碼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

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

void removeChar(char *str, unsigned int index) {
    char *src;
    for (src = str+index; *src != '\0'; *src = *(src+1),++src) ;
    *src = '\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!
#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;
}
#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)

現在你所要做的就是重新加入這兩個部分。

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

使用strcat()連接字符串。

但是strcat()不允許重疊,因此您需要創建一個新字符串來保存輸出。

以下應該這樣做:

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

我嘗試使用strncpy()snprintf()

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

我知道這個問題很老了,但我將把我的實現留在這里:

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

只需將不等於要刪除的字符的字符扔到新字符串中。

這是一種非常基本的方法:

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

我很驚訝 10 多年來發布的答案都沒有提到這一點:

  • 使用strncpy(word2, word, strlen(word)-1);復制沒有最后一個字節的字符串; 不正確:不會在word2[strlen(word) - 1]處設置空終止符。 此外,如果word是空字符串(沒有最后一個字符),此代碼將導致崩潰。

函數strncpy不是解決這個問題的好選擇。 事實上,不推薦任何問題,因為如果n參數小於等於源字符串長度,它不會在目標數組中設置空終止符。

這是一個簡單的通用解決方案,用於在刪除偏移量pos處的字符時復制字符串,它不假定pos是字符串內的有效偏移量:

#include <stddef.h>

char *removeat_copy(char *dest, const char *src, size_t pos) {
    size_t i;
    for (i = 0; i < pos && src[i] != '\0'; i++) {
        dest[i] = src[i];
    }
    for (; src[i] != '\0'; i++) {
        dest[i] = src[i + 1];
    }
    dest[i] = '\0';
    return dest;
}

如果dest == src ,此函數也有效,但要刪除可修改字符串中的字符,請使用以下更有效的版本:

#include <stddef.h>

char *removeat_in_place(char *str, size_t pos) {
    size_t i;
    for (i = 0; i < pos && str[i] != '\0'; i++)
        continue;
    for (; str[i] != '\0'; i++)
        str[i] = str[i + 1];
    return str;
}

最后,這里是使用庫函數的解決方案:

#include <string.h>

char *removeat_copy(char *dest, const char *src, size_t pos) {
    size_t len = strlen(src);
    if (pos < len) {
        memmove(dest, src, pos);
        memmove(dest + pos, src + pos + 1, len - pos);
    } else {
        memmove(dest, src, len + 1);
    }
    return dest;
}

char *removeat_in_place(char *str, size_t pos) {
    size_t len = strlen(str);
    if (pos < len) {
        memmove(str + pos, str + pos + 1, len - pos);
    }
    return str;
}

這就是我在 C++ 中實現相同的方式。

#include <iostream>
#include <cstring>

using namespace std;

int leng;
char ch;
string str, cpy;

int main() {
    cout << "Enter a string: ";
    getline(cin, str);
    leng = str.length();
    cout << endl << "Enter the character to delete: ";
    cin >> ch;
    for (int i=0; i<leng; i++) {
        if (str[i] != ch)
        cpy += str[i];
    }
    cout << endl << "String after removal: " << cpy;
    return 0;
}

擺脫 \0 的一種方便、簡單和快速的方法是在 strncpy 而不是 strcpy 的幫助下復制沒有最后一個字符 (\0) 的字符串:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM