Как заменить два символа одним символом?

#c #loops #char #c-strings

#c #циклы #символ #c-строки

Вопрос:

Итак, я пытаюсь заменить cc на amp; в предложении (например: "Hi this is Mark cc Alice" ). Пока у меня есть этот код, в котором он заменяет первый c на amp; , но второй c все еще существует. Как бы мне избавиться от второго c ?

 int main() {
    char str[] = "Hi this is Mark cc Alice";
    int i = 0;
    while (str[i] != '') {
        if (str[i] == 'c' amp;amp; str[i   1] == 'c') {
            str[i] = 'amp;';  
            //str[i   1] = ' ';
        }
        i  ;
    }
    printf("n-------------------------------------");
    printf("nString After Replacing 'cc' by 'amp;'");
    printf("n-------------------------------------n");
    printf("%sn",str);
    return str;
}
  

Входные данные:

 Hi this is Mark cc Alice
  

Вывод:

 Hi this is Mark amp;c Alice
  

Ответ №1:

Вы можете просто перетасовать его на одно место, используя общую функцию «переместить назад»:

 void shunt(char* dest, char* src) {
  while (*dest) {
    *dest = *src;
      dest;
      src;
  }
}
  

Где вы можете использовать его следующим образом:

 int main(){
  char str[] = "Hi this is Mark cc Alice";

  for (int i = 0; str[i];   i) {
    if (str[i] == 'c' amp;amp; str[i 1] == 'c') {
      str[i]='amp;';

      shunt(amp;str[i 1], amp;str[i 2]);
    }
  }

  printf("n-------------------------------------");
  printf("nString After Replacing 'cc' by 'amp;'");
  printf("n-------------------------------------n");
  printf("%sn",str);

  // main() should return a valid int status code (0 = success)
  return 0;
}
  

Обратите внимание на переход от беспорядочного int объявления while increment в один for цикл. Это было бы еще менее грязно, используя char* вместо этого указатель:

 for (char* s = str; *s;   s) {
  if (s[0] == 'c' amp;amp; s[1] == 'c'){
    *s = 'amp;';

    shunt(amp;s[1], amp;s[2]);
  }
}
  

При работе со строками C важно, чтобы вам было удобно работать с указателями, так как это может избавить вас от многих хлопот.

Вам также следует ознакомиться со стандартной библиотекой C, чтобы вы могли использовать такие инструменты, как strstr вместо написания собственного эквивалента same . Здесь strstr(str, "cc") могло бы помочь.

Комментарии:

1. Вы могли бы просто использовать memmove(str i 1, str i 2, strlen(str i 2) 1);

2. @chqrlie не был уверен, насколько безопасно memmove будет использовать перекрывающийся источник / цель.

3. memmove специально разработан для правильной обработки перекрывающихся областей, в отличие memcpy от .

Ответ №2:

Вы должны сдвинуть весь массив влево. Простой способ сделать это :

 #include <stdio.h>
#include <string.h>

#define STR_SIZE 25

int main(){
  char str[STR_SIZE] = "Hi this is Mark cc Alice";
  int i=0,j=0;

  while(str[i]!=''){
    if(str[i]=='c' amp;amp; str[i 1]=='c'){ 
      str[i]='amp;';
      for (j=i 1; j<STR_SIZE-1; j  ) /* Shifting the array to the left */
      {
          str[j]=str[j 1];
      }
    }
    i  ;
  }
  printf("n-------------------------------------");
  printf("nString After Replacing 'cc' by 'amp;'");
  printf("n-------------------------------------n");
  printf("%sn",str);
  return 0;
}
  

Комментарии:

1. Здесь нет необходимости STR_SIZE . Если что-то, что вызывает проблемы, если эта строка когда-нибудь станет длиннее.

Ответ №3:

Вы можете использовать метод 2 пальца: используйте отдельные индексные переменные для чтения и записи символов в одном массиве.

 #include <stdio.h>
#include <string.h>

int main() {
    char str[] = "Hi this is Mark cc Alice";
    int i = 0, j = 0;

    while (str[i] != '') {
        if (str[i] == 'c' amp;amp; str[i   1] == 'c') {
            str[j  ] = 'amp;';
            i  = 2;
        } else {
            str[j  ] = str[i  ];
        }
    }
    str[j] = '';  // set the null terminator that was not copied.

    printf("n-------------------------------------");
    printf("nString After Replacing 'cc' by 'amp;'");
    printf("n-------------------------------------n");
    printf("%sn", str);
    return 0;
}
  

Ответ №4:

не меняя большую часть своего кода, вы также можете сделать это следующим образом

 #include <stdio.h>

int main()
{
  char str[] = "Hi this is Mark cc Alice";
  int i=0;
  while(str[i]!='')
  {
    if(str[i]=='c' amp;amp; str[i 1]=='c')
    {
      str[i]='amp;'; 
      // after replacing the first 'c' increment the i, so it will point to next c.
      i  ;
      break;
      //str[i 1]=' ';
    }
    i  ;
  }
  // replace previous char with next char until null
  while(str[i]!='')
  {
      str[i] = str[i 1];
      i  ;
  }
  printf("n-------------------------------------");
  printf("nString After Replacing 'cc' by 'amp;'");
  printf("n-------------------------------------n");
  printf("%sn",str);
  return 0;
}
  

Комментарии:

1. Кроме того, @RainbowUnicorn, вы возвращаетесь str в конце main, это неверно, просто используйте return 0;