Замена слово/значение в текстовом файле

285
29 июля 2021, 02:20

Cтолкнулся с такой проблемой,мне необходимо изменить значение в строке(которую находит с помощью ключа). Проблема в том, что мне неизвестно это значение. Нахожу строку с помощью ключа, но не удаётся изменить значение, которое идёт последовательно после этого ключа, также как эту строку записать обратно в исходный файл.Буду очень признателен за советы и помощь!

void checkfile(string password,string login,string sum)
{
    ifstream fin;
    fin.open("base.txt");
    ofstream fout("replaced.txt");
    for (string line; !fin.eof(); getline(fin, line))
    {
        string sin(line.substr(line.find("=") + 1));
        if (line.find(login) != string::npos)
        {
            if (line.find(password) != string::npos)
            {
                 line.replace(line.find(password)+1, sum.size(), sum);
            }
        }
        fout << line << '\n';
    }
    fin.close();
}

В base.txt записано строки так :

str str123 0
hello world 0
...
(Мне надо именно  3 значение менять)
Answer 1

Если у вас могут быть разные строки - с чем-то лишним или нехваткой (не ровно три слова), то я бы делал через строчный поток.

void checkfile(string password, string login, string sum) {
    ifstream fin;
    fin.open("base.txt");
    ofstream fout("replaced.txt");
    for (string line; getline(fin, line);) {
        istringstream in(line);
        string l, p;
        if (in >> l >> p && l == login && p == password) {
            fout << l << " " << p << " " << sum << '\n';
            }
        else
            fout << line << "\n";  // Старая строка
        }
    fin.close();
    }

Я добавил вывод неизмёненной строки, не знаю, у вас его нет.

Если есть гарантия, что в каждой строке в файле ровно три слова - то можно проще:

void checkfile(string password, string login, string sum) {
    ifstream fin;
    fin.open("base.txt");
    ofstream fout("replaced.txt");
    for (string l, p, s; fin >> l >> p >> s;) {
        if (l == login && p == password) {
            fout << l << " " << p << " " << sum << "\n";
            }
        else
            fout << l << " " << p << " " << s << "\n";  // Старая строка
        }
    fin.close();
    }

Просто проверять наличие логина и пароля, по-моему, мало - вдруг у кого-то логин, как пароль, а пароль, как логин у кого-то другого?

Answer 2
  1. Аргументы функции не нужно копировать, и нужно указать, что они не меняются, также нужно иметь возможность использовать временные переменные, поэтому передайте по константной ссыльке.
  2. Передайте в вашу функцию также имя файла или сам файловый обьект, для удобства дальнейшего использования функции.

Абсолютно не нужно иметь дополнительные обьекты для хранения того, что прочитали. Достаточно зафиксировать позицию, где нам нужно остновиться, а потом работать с этого места. А если хотите заменить в файле что то, то откройте его и для чтения и для записи Это покажу на примере:

void 
checkfile(std::fstream& fout, const std::string& password, 
    const std::string& login, const std::string& sum)
{   
   //проверка на открытие файла выполняется 
   //до вызова функции или выпоняйте здесь
    std::string s1, s2;
    std::streampos pos = 0;
    while (fout >> s1 >> s2) {
        if (s1 == login && s2 == password) {
            //игнорирум все пробелы 
            while (fout.peek() == ' ') fout.ignore();
            //получим текущую позицию чтения
            pos = fout.tellg();
            //установим позицию для записи начиная от pos 
            fout.seekp(pos, std::ios::beg);
            //и запиываем нашу строку
            fout << sum;
            /*(можете заппомнить эту позицию для
            дальнейшей записи там старой  строки)
            дальше игнорируем всю оставшуюся строку
            и переходим на следующую */
            fout.ignore(100, '\n');
        }
    }
    fout.close();   
}
READ ALSO
вывод промежуточных данных в строку таблицы c#

вывод промежуточных данных в строку таблицы c#

Есть веб-форма, на которой существует несколько выпадающих списков и некая таблица с заполненными даннымиполе Pocket_num соответствует выбору...

172
Событие добавления элемента в Hashtable

Событие добавления элемента в Hashtable

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

302