如何使用C在char数组中用另一个char替换两个char?

时间:2017-08-02 14:44:28

标签: c arrays loops for-loop while-loop

问题是;我需要在字符串中用“C”替换“AB”。

示例1:

  

“HEABLO”到“HECLO”

代码:

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

没有错误,也没有输出。

5 个答案:

答案 0 :(得分:1)

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

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

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

上面描述的方法不像替换所有出现的子字符串那样高效,因为字符串的整个尾部被移动,包括要替换的子字符串的剩余实例,每次都substr_char()叫做。可以修改此方法,以便通过编写单个函数来替换替换子字符串的所有实例,从而不会复制额外的字符。此函数substr_char_all()查找子字符串的第一个实例,并将替换字符写入next指示的位置,然后在tail中查找子字符串的下一个实例。如果没有此类实例,则移动tail以跟随替换字符。如果存在子字符串的另一个实例,则移动此实例之前的字符以跟随替换字符。通过从tail减去loc来找到要移动的字符数,因为tail指向字符串剩余部分的开头,而loc指向开头的tail下一个子字符串实例。请注意,locptrdiff_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); } } } 以指示移动字符后面的位置,循环继续,将替换字符写入下一个位置,并搜索替换子字符串的更多实例。

Before substitution: heablo
After substitution: hello

Before substitution: heababababloo
After substitution: hellllloo

Before substitution: heablo
After substitution: hello

Before substitution: heababababloo
After substitution: hellllloo

Before substitution: some body wants some thing
After substitution: a body wants a thing

节目输出:

{{1}}

答案 1 :(得分:0)

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

if(i==strlen(a))

您的示例字符串长度为6个字符。因为你的解决方案不起作用(除了将'AB'的'A'替换​​为'C'之外你不改变字符串)字符串的长度不会改变。因此,当您退出while循环时,i的值将为strlen(a)-1,其值可能与strlen(a)不同。

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

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

答案 2 :(得分:0)

这个怎么样:

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

答案 3 :(得分:0)

这可能是达到你想要的最简单方法。只发生一次。

char* o=input;
char* i=input;
for(;*o=*i;i++,o++)
    *o=(i[0]=='a' && i[1]=='b' && i++)? 'c': *i;

以下是DEMO

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

我希望这个有助于更好地理解。上面提到的只是一种紧凑(可能很复杂)的方式来编写相同的逻辑。

答案 4 :(得分:0)

你的程序没有输出任何东西,因为 你循环直到你连续找到'a'和'b'。

所以对于i = 4你发现一个[i] ='a'和一个[i + 1] ='b',因为它找到了一个[j] ='\ 0',其中j = 0。所以你的字符串“HEABLO”变成了这样的“\ 0EABLO”

当你执行strlen(a)时它返回0并且我的值为4因为你使用了continue语句而i值没有增加它保持在4。

现在在while循环中检查4&lt; 0它失败了,同样如果条件语句也失败了因为if(4 == 0)所以printf没有被执行

执行任务的简单代码:)

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