Замена символа в строке
Возможный дубликат:
Что такое функция для замены строки в C?
Я пытаюсь заменить определенный символ в моей строке несколькими символами. Вот пример того, что я пытаюсь сделать.
Скажем, у меня есть строка "ааабаа"
Я хочу заменить все вхождения символа "b" на 5 "c" s.
Поэтому, когда я закончу, "aaabaa" становится "aaacccccaa"
Я написал следующий код:
#include <stdio.h>
#include <string.h>
int main(void)
{
char s[20] = "aaabaa";
int i, j;
for (i=0; s[i]!= '\0'; i++)
{
if (s[i] == 'b')
{
for (j=0; j<5; j++)
{
s[i+j] = 'c';
}
}
}
printf("%s\n", s);
}
Мой вывод из этой функции "aaaccccc". Похоже, что он просто перезаписывает последние два буквы "с". Есть ли какой-нибудь способ, которым я бы хотел, чтобы эти последние пару не перезаписывались?
7 ответов
Ваша проблема в том, что вы заменяете "ccccc" на исходную строку, перезаписывая оставшиеся символы после того, что хотите заменить... Вы должны скопировать в новую строку и отслеживать два индекса - по одному в каждом.
И будь счастлив, что ты объявил char s[20]
больше, чем размер вашей исходной строки плюс значения замены, иначе вы бы создали уязвимость переполнения буфера в вашей критической системе входа в систему:-)
Ура,
Если вы хотите сделать это в целом, не беспокоясь о том, чтобы пытаться определить размер ваших буферов, вам следует malloc
новая строка, достаточно большая, чтобы вместить результат:
/* return a new string with every instance of ch replaced by repl */
char *replace(const char *s, char ch, const char *repl) {
int count = 0;
const char *t;
for(t=s; *t; t++)
count += (*t == ch);
size_t rlen = strlen(repl);
char *res = malloc(strlen(s) + (rlen-1)*count + 1);
char *ptr = res;
for(t=s; *t; t++) {
if(*t == ch) {
memcpy(ptr, repl, rlen);
ptr += rlen;
} else {
*ptr++ = *t;
}
}
*ptr = 0;
return res;
}
Использование:
int main() {
char *s = replace("aaabaa", 'b', "ccccc");
printf("%s\n", s);
free(s);
return 0;
}
Вы можете использовать другую переменную
#include <stdio.h>
#include <string.h>
int main(void)
{
char s[20] = "aaabaa";
char temp[20]="";
int i, j,k;
k=0;
for (i=0; s[i]!= '\0'; i++)
{
if (s[i] == 'b')
{
for (j=0; j<5; j++)
{
temp[k] = 'c';
k++;
}
}
else
{
temp[k]=s[i];
k++
}
}
printf("%s\n", temp);
}
Необходимо объявить второй массив символов. В приведенном ниже коде он просто копирует содержимое массива s в s1, когда условие не выполняется.
#include <stdio.h>
#include <string.h>
int main(void)
{
char s[20] = "aaabaa";
char s1[1024];
int i, j, n;
for (i=0, n = 0; s[i]!= '\0'; i++)
{
if (s[i] == 'b')
{
for (j=0; j<5; j++)
{
s1[n] = 'c';
n++;
}
}
else
{
s1[n] = s[i];
n++;
}
}
s1[n] = '\0';
printf("%s\n", s1);
}
#include <stdio.h>
#include <string.h>
int main(void)
{
char temp[20];
char s[20] = "aaabaa";
int i, j;
for (i=0; s[i]!= '\0'; i++)
{
if (s[i] == 'b')
{
strcpy(temp,s[i+1]); //copy rest of the string in this case 'aa'
for (j=0; j<5; j++)
{
s[i+j] = 'c';
}
s[i+j] = '\0'; // here we get s = "aaaccccc"
strcat(s,temp); // concat rest of the string (temp = "aa") after job is done.
// to this point s becomes s = "aaacccccaa"
}
}
printf("%s\n", s); //s = "aaacccccaa".
}
здесь мы используем буфер (temp) для хранения оставшейся части строки после нашего заменяемого символа. после замены мы добавляем его до конца.
поэтому мы получаем s = "aaacccccaa"
Что ж, если вы собираетесь динамически размещать массив, вам, вероятно, придется выделить второй массив. Это необходимо, потому что вашей строке s выделено только фиксированное количество памяти.
Итак, вместо того, чтобы пытаться перезаписать символы в вашем цикле for, я бы предложил увеличить счетчик, который говорит вам, насколько большим должен быть ваш новый массив. Ваш счетчик должен начинаться с размера вашей исходной строки и увеличиваться на 4 каждый раз, когда обнаруживается экземпляр 'b'. После этого вы сможете написать функцию, которая соответствующим образом копирует измененную строку в новый символьный буфер размера [counter], вставляя 5 c каждый раз, когда обнаруживается a 'b'.
Используйте эту функцию:
char *replace(char *st, char *orig, char *repl) {
static char buffer[4096];
char *ch;
if (!(ch = strstr(st, orig)))
return st;
strncpy(buffer, st, ch-st);
buffer[ch-st] = 0;
sprintf(buffer+(ch-st), "%s%s", repl, ch+strlen(orig));
return buffer;
}
для вашего случая: printf("%s\n", replace(s,"b","ccccc"));