Про вектор из строк string и быструю замену строк методами класса string
Вот здесь подобный код уже есть, а сегодня возникло небольшое недоумение по поводу
while ((ch = file.get()) != EOF)
Выделенные жирным скобки здесь именно обязательны, если их убрать, то получим логику
while (ch = (file.get() != EOF))
так как у операций отношения (равно, не равно) приоритет выше, чем у присваивания
(табл. 3.3) и, в результате, в переменную ch
будут записаны не очередные символы, прочитанные из файла, а "единички" для всех символов, не равных концу файла :)
Так как была задача ещё и осуществить в прочитанном из файла (посимвольным или построчным чтением) векторе строк замену одной подстроки на другую (длины строк необязательно совпадают), в показанном листинге есть простейшее решение и этой задачки.
Нужно понимать, что любая операция со строкой, требующая по ней больше одного прохода, не есть хорошо. Культурней, но и обычно более трудоёмко, написать какой-то вот такой
классический код. Кроме того, есть стандартный алгоритм replace, который можно приспособить и для строк, а есть отличные возможности класса string
по поиску и замене:
#include <iostream> #include <string> #include <clocale> using namespace std; int main() { setlocale(LC_ALL,"Rus"); int pos = 0; int match_pos; string target = "Около колокола околачивались колокольчики."; string oldVal = "ко"; //что заменяем string newVal = "кококо"; //на что cout << endl << "Target:"; cout << endl << target; string::size_type n = 0; while ((n = target.find(oldVal, n)) != string::npos) { target.replace(n, oldVal.size(), newVal); n += newVal.size(); } cout << endl << "Result:"; cout << endl << target; cin.get(); return 0; }
Target: Около колокола околачивались колокольчики. Result: Окококоло кококолокококола окококолачивались кококолокококольчики.
Так как здесь поиск нового вхождения начинается с места, где закончилось предыдущее вхождение, можно считать, что делаем один проход :)
Также обратите внимание, что здесь искомая строка изменяется "на месте" и оказывается с заменами по завершении цикла while
.
И вот наш начальный листинг, файл для примера формируется тоже программно в текущей папке.
Коды заметки проверены в консоли Visual Studio 2015.
#include <iostream> #include <fstream> #include <vector> #include <string> #include <clocale> using namespace std; int main() { setlocale(LC_ALL, "Rus"); vector <string> v; //Создаем файл с данными для теста ofstream w("data.txt"); string data("I'm software engineer,\n\ Get\n\ me\n\ out\n\ of here!\n\ Прагма #абырвалг\n\ here is ere of something"); w << data; w.close(); //Читаем его посимвольно, но в вектор строк ifstream f("data.txt"); string s; int ch = 0; while ((ch = f.get()) != EOF) { if ((char)ch != '\n') s += (char)ch; else { v.push_back(s); s.clear(); } } if (!s.empty()) v.push_back(s); f.close(); //Теперь строки файла в векторе v, делаем поиск и замену string search = "er"; //строка для поиска string repl = "!!!"; //строка для замены for (unsigned int i = 0; i < v.size(); i++) { unsigned int n = 0; //начальная позиция поиска do { n = v[i].find(search, n); if (n != string::npos) { v[i].replace(n, search.size(), repl); } else break; } while (1); cout << (i + 1) << ") " << v[i] << endl; } cin.get(); return 0; }
23.04.2019, 16:08 [1553 просмотра]