问题是;我需要在字符串中用“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;
}
没有错误,也没有输出。
答案 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
下一个子字符串实例。请注意,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);
}
}
}
以指示移动字符后面的位置,循环继续,将替换字符写入下一个位置,并搜索替换子字符串的更多实例。
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;
}