C ++ найти / заменить строки

0

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

Я работаю над проектом, где мне нужно ввести строку (String1), а затем найти определенную строку (String2) внутри String1. Затем мне нужно заменить String2 на новую строку (String3).

Надеюсь, это имеет смысл. В любом случае, я могу достичь желаемого результата, но он ситуативен. На код, и я объясню по дороге.

int main()
{
    string string1, from, to, newString;

    cout << "Enter string 1: ";
    getline(cin, string1);

    cout << "Enter string 2: ";
    cin >> from;

    cout << "Enter string 3: ";
    cin >> to;  

    newString = replaceSubstring(string1, from, to);

    cout << "\n" << newString;
}

string replaceSubstring(string string1, string from, string to)
{
        int index, n, x = 0;

        n = from.length();

        while (x < string1.length() - 1)
        {
            index = string1.find(from, x);
            string1.replace(index, n, to);
            x = index + to.length() - 1;
        }
        return string1;
}

Я должен указать следующее: "Он долгое время жил в этом маленьком городке, окончил его в 1950 году".

И тогда я должен заменить все экземпляры "Он" на "Она".

Когда я пытаюсь это сделать, я получаю следующую ошибку:

terminate call после вызова экземпляра 'std :: out_of_range'
what(): basic_string :: replace
Прерывание (сбрасывание ядра)

Однако, если я вхожу что-то вроде.

String1 = "Он Он"
String2 = "He"
String3 = "She"

Он будет выводить:

"Она Она"

  • 3
    Замена "string1", "string2" и "string3" значимыми именами переменных облегчит определение поведения вашей программы.
  • 0
    Я сделал пару небольших правок, чтобы изменить переменные. String2 = От и String3 = До. Так как я меняюсь со строки2 на строку3.
Показать ещё 2 комментария
Теги:
string
find
replace

3 ответа

1
Лучший ответ

Прежде всего, было бы лучше, если бы функция изменила исходную строку "на месте". В этом случае он будет выглядеть как универсальная функция, заменяющая аналогичную замену функции-члена.

Вы должны проверить, будет ли индекс после вызова

index = string1.find(string2, x);

равно std::string::npos. В противном случае функция выдает исключение.

Также это утверждение

x = index + to.length() - 1;

неправильно

Он должен выглядеть

x = index + to.length();

Например, предположим, что у вас есть строка со значением "a" и вы хотите заменить ее на "ba". В этом случае, если использовать ваш оператор x будет равен 1 (x = 0 + 2 - 1). и укажет на "a" в "ba". И функция снова заменит "a" на "ba", и вы получите "bba" и так далее. То есть цикл будет бесконечным.

Я бы написал функцию следующим образом

#include <iostream>
#include <string>

void replace_all( std::string &s1, const std::string &s2, const std::string &s3 )
{
    for ( std::string::size_type pos = 0;
          ( pos = s1.find( s2, pos ) ) != std::string::npos;
          pos += s3.size() )
    {
        s1.replace( pos, s2.size(), s3 );
    }
}

int main() 
{
    std::string s1( "Hello world, world, world" );
    std::string s2( "world" );
    std::string s3( "mccdlibby" );

    std::cout << s1 << std::endl;

    replace_all( s1, s2, s3 );

    std::cout << s1 << std::endl;

    return 0;
}

Выход

Hello world, world, world
Hello mccdlibby, mccdlibby, mccdlibby
  • 0
    Спасибо, это очень помогло!
  • 0
    @mccdlibby Добро пожаловать.
2

Когда ваш вызов FIND завершится неудачно, у вас будет неправильный index в этой области:

   index = string1.find(string2, x);
   string1.replace(index, n, string3);

Проверьте значение index перед его Replace на Replace

  • 0
    Я делаю некоторые проверки ошибок в данный момент.
  • 2
    не в коде вы опубликовали
Показать ещё 3 комментария
1

Функция поиска возвращает начальный индекс string x и начало индекса от 0 to len-1 вместо 1 to len.

int idx = string1.find(string2, x);
if(idx >= 0)
    string1.replace(index, n, string3);
  • 0
    В общем случае это неправильный код. Например, если исходная строка очень длинная и std :: string :: size_type равен 8 байтам, а int равен 4 байтам, когда вы получите неопределенное поведение.
  • 1
    если должно быть idx> std :: string :: npos

Ещё вопросы

Сообщество Overcoder
Наверх
Меню