如何使用C将字符数组中的两个字符替换为另一个字符?

如何使用C将字符数组中的两个字符替换为另一个字符?,c,arrays,loops,for-loop,while-loop,C,Arrays,Loops,For Loop,While Loop,问题是,;我需要用字符串中的C替换AB 例1: 希布洛到赫克洛 代码: int main() { int i=0,j=0; char a[]="helablo"; while(i<strlen(a)-1){ if(a[i]=='a'&& a[i+1]=='b'){ a[j]='\0'; a[j++]='c'; continue; }

问题是,;我需要用字符串中的C替换AB

例1:

希布洛到赫克洛

代码:

    int main() {
    int i=0,j=0;
    char a[]="helablo";
    while(i<strlen(a)-1){
        if(a[i]=='a'&& a[i+1]=='b'){
            a[j]='\0';
            a[j++]='c';
            continue;
        }
        i++;
    }
    if(i==strlen(a)){
        printf("%s\n",a);
    }
    a[j]='\0';
    return 0;
}

没有错误,也没有输出。

没有输出,因为您明确地将其编码为仅在一种特定情况下输出某些内容……这是永远不会发生的。此if语句中的表达式将始终为false

if(i==strlen(a))
您的示例字符串长度为6个字符。因为您的解决方案不起作用,所以您不会更改字符串,除非将'AB'的'A'替换为'C',否则字符串的长度不会更改。因此,当您退出while循环时,i的值将是strlena-1,它不可能与strlena相同

有很多方法可以做你想做的事。一种可能的解决方案是使用第二个字符串将结果复制到中,然后再像这样将其复制回来

int i,j;
char a[]="helablo";
char *b;
b=malloc(strlen(a)+1);

for(i=0,j=0;a[i]!='\0';i++)
  {
  if((a[i]=='a')&&(a[i+1]=='b'))
    {
    b[j++]='c';
    i++;
    }
  else
    {
    b[j++]=a[i];
    }
  }
b[j]='\0';
strcpy(a,b);
free(b);
printf("%s\n",a);

您可以编写一个更通用的函数,用单个字符替换子字符串,使用strstr查找子字符串,使用memmove重写字符串的结尾

strstr函数查找输入字符串中第一个出现的子字符串,如果未找到匹配项,则返回空指针。此指针可用于将所需的字符分配给输入字符串。然后可以使用memmove将字符从字符串末尾移动到替换字符后面的位置。如果loc是指向找到的子字符串位置的指针,replace_len是要替换的子字符串的长度,则char*tail=loc+replace_len指向应保留的输入字符串的尾部,strlentail+1是要移动的字符数,包括“\0”字符

此函数仅替换子字符串的第一次出现;如果需要替换子字符串的所有匹配项,可以在循环中调用此函数。由于substr_char在未进行替换时返回被替换字符后面的字符指针或空指针,因此可以在循环中使用返回值继续进行替换,直到找不到更多匹配项为止

由于每次调用substr_char时都会移动字符串的整个尾部,包括要替换的子字符串的剩余实例,因此上述方法在替换所有出现的子字符串时可能没有效率。可以修改此方法,以便通过编写单个函数来替换替换子字符串的所有实例,不会复制额外的字符。此函数substr_char_all查找子字符串的第一个实例,并将替换字符写入next指示的位置,然后在尾部查找子字符串的下一个实例。如果没有这样的实例,则将尾部移动到替换字符后面。如果存在子字符串的另一个实例,则此实例前面的字符将移动到替换字符后面。要移动的字符数是通过从loc中减去tail得到的,因为tail指向字符串其余部分的开始,loc指向下一个子字符串实例的开始。请注意,tail和loc都是指针,因此存储此结果的正确类型是ptrdiff\t。然后递增指针next,以指示移动字符后面的位置,循环继续,将替换字符写入下一个位置,并搜索替换子字符串的更多实例

#include <stdio.h>
#include <string.h>
#include <stddef.h>           // for ptrdiff_t, used in substr_char_all()

char * substr_char(char *str, char *substr, char c);
void substr_char_all(char *st, char *subst, char c);

int main(void)
{
    /* Replace the first occurrence of a substring with a character */
    char string1[] = "heablo";
    printf("Before substitution: %s\n", string1);
    char *found = substr_char(string1, "ab", 'l');
    printf("After substitution: %s\n", string1);

    putchar('\n');

    /* Replace all occurrences of a substring with a character */
    char string2[] = "heababababloo";
    printf("Before substitution: %s\n", string2);
    found = string2;
    while ((found = substr_char(found, "ab", 'l'))) {
        continue;
    }
    printf("After substitution: %s\n", string2);

    /* Using the substr_char_all() function */
    putchar('\n');
    char string3[] = "heablo";
    printf("Before substitution: %s\n", string3);
    substr_char_all(string3, "ab", 'l');
    printf("After substitution: %s\n", string3);

    putchar('\n');
    char string4[] = "heababababloo";
    printf("Before substitution: %s\n", string4);
    substr_char_all(string4, "ab", 'l');
    printf("After substitution: %s\n", string4);

    putchar('\n');
    char string5[] = "some body wants some thing";
    printf("Before substitution: %s\n", string5);
    substr_char_all(string5, "some", 'a');
    printf("After substitution: %s\n", string5);

    return 0;
}

/* Returns a pointer to the character following substitution, or NULL */
char * substr_char(char *st, char *subst, char c)
{
    char *loc = strstr(st, subst);
    if (loc) {
        *loc = c;
        char *tail = loc + strlen(subst);
        memmove(loc + 1, tail, strlen(tail) + 1);
        ++loc;
    }

    return loc;
}

void substr_char_all(char *st, char *subst, char c)
{
    char *loc = strstr(st, subst);
    char *next = loc;
    while (loc) {
        *next++ = c;
        char *tail = loc + strlen(subst);
        if ((loc = strstr(tail, subst))) {
            ptrdiff_t copy_len = loc - tail;
            memmove(next, tail, copy_len);
            next += copy_len;
        } else {
            memmove(next, tail, strlen(tail) + 1);
        }
    }
}
这个怎么样:

#include<stdio.h>
#include<string.h>
int main() {
    int i=0,j=0;
    char a[]="helablo";
    for(int i=0;a[i]!='\0';i++){
        if(a[i]=='a'&& a[i+1]=='b'){
            a[i]='c';
            for(j=i+1;j<strlen(a);j++){
                a[j]=a[j+1];
            }
        }
    }
    printf("%s\n",a);
    return 0;
}

这可能是实现你想要的最简单的方法。一次就发生了

char* o=input;
char* i=input;
for(;*o=*i;i++,o++)
    *o=(i[0]=='a' && i[1]=='b' && i++)? 'c': *i;
这是你的电话号码

for循环只是将一个字母从输入位置一次复制到输出位置1个字符。此循环将持续到*i不是0'\0'

因此,基本上不会发生任何变化。但内部的行检查输入是否在其写入的位置同时具有a和b。如果是这样,则对条件的第三部分进行求值,从而使其从输入中跳过一个字符

当它的计算结果为true时,将使用“c”写入输出。否则它将覆盖旧值

同样的代码以一种简单的方式如下所示

for (; *input != '\0'; i++) {
    if( input[0] == 'a' && input[1] == 'b'){
        input++;
        *output = 'c';
    } else {
        *output = *input;
    }
    output++;
}

我希望这有助于更好地理解。上面提到的方法只是编写相同逻辑的一种简单而复杂的方法。

您的程序不会输出任何东西,因为 你不断循环直到找到a和b

因此,对于i=4,您找到了一个[i]='a'和一个[i+1]='b',因为它找到了一个[j]='\0',其中最初的j=0

当您执行strlena时,它返回0,i的值为4,因为您使用了continue语句,i的值没有增加,而是保持在4


现在,在while循环中,您不能用一个数组元素替换两个数组元素。额外的空间会发生什么变化?a[j]='\0';为什么要这样做。使用调试器并逐步完成代码。你会学到很多!不要编写像@BLUEPIXY这样的补丁,不知道你到底做了什么
但我确实意识到我忘了跳过匹配的“b”,它仍然有一个错误。@BLUEPIXY它可能并不完美,但它现在完成了OP要求的a[I]!='\0'| | a[i+1]!='\“0”绝对不好。@IngoLeonhardt跳过了最后一个字符。如果我做对了,这不是^2上的复杂性吗?不过这可以一次完成。@AjayBrahmakshatriya-我不太关心这里的效率,但我在回答中添加了一个函数,它使用strstr和memmove,同时避免了额外的复制。欢迎使用StackOverflow,感谢您的帮助。你的回答似乎很有说服力。但是你想把这个部分改一下吗。。。因为它被发现了…,所以读起来有点笨重。在句子的开头加上一些大写字母,或者在代码部分加上一些格式,可能会有一些小的改进。对于一个好的解释来说,这并不是真正必要的,但也可能是一个改进,这将是一个演示所描述的解决方案的代码。玩得开心。你能解释一下吗*o=*i;i++,o++*o=i[0]='a'和&i[1]='b'和&i++?'c':*i@Aravind我在回答中添加了解释。
#include<stdio.h>
#include<string.h>
int main()
{
   char a[]="helabablo";
   char *p=a;
   while(*(p+1)!='\0')
   {
     if(*p=='a'&&*(p+1)=='b')
     {
       *(p++)='l';
       *(p++)='\0';
       strcat(a,p);
       p-=2;
     }
     p++;
   }
   printf("%s\n",a);
   return 0;
}