Форум программистов, компьютерный форум CyberForum.ru

"вставка" с "заменой" текста в файле. - C++

Восстановить пароль Регистрация
 
Razzeeyy
 Аватар для Razzeeyy
30 / 7 / 2
Регистрация: 01.03.2011
Сообщений: 95
01.10.2011, 18:59     "вставка" с "заменой" текста в файле. #1
Здравствуйте.
Решил для обретения бесценного опыта написать свой простенький парсер конфигов.
Вообщем читает вполне себе читает конфиг.. пишет его... но вот столкнулся с вопросом, который вновинку и ума не приложу как это реализовать.

Надо мне сделать так, что если в конфиг пишутся две одинаковые строки, то одна другую "затирает".
Как это реализовать? емнип в классе fstream нету что то вроде find() чтобы найти вхождение строки в файл.


P.S. для большего пояснения, у меня конфиг по структуре выглядит примерно так

Код
section "default"
value1 "1"
value2 "anything else"
more "something"
section может быть сколько угодно много, есть функция которой определяем с какой секцией мы решили работать. эта самая функция построчно анализирует файл и если найдено вхождение с "section \"+name+"\"" то парсит имя параметра и его значения в map <string, string> section_buf.
вот думаю как же делать так чтобы при записи секции обратно в файл она корректно заменяла другую...
пробегала мысль складывать всё содержимое файла в какой нибудь string buffer и уже по нему потом искать и с ним работать. а при завершении работы просто перезаписывать файл содержимым string buffer.
но мне не кажется что это будет оптимально, думаю в языке есть какие-то "стандартные" средства для решения моей проблеммы.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
-=ЮрА=-
Заблокирован
Автор FAQ
01.10.2011, 19:10     "вставка" с "заменой" текста в файле. #2
Цитата Сообщение от Razzeeyy Посмотреть сообщение
fstream нету что то вроде find()
- зато есть tellg(возврат позиции курсора в файл) и seekg перемещение курсора в заданную позицию. Установив курсор на нудное место в файле, осуществите в него вывод и посмотрите что будет...
Razzeeyy
 Аватар для Razzeeyy
30 / 7 / 2
Регистрация: 01.03.2011
Сообщений: 95
01.10.2011, 19:37  [ТС]     "вставка" с "заменой" текста в файле. #3
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
зато есть tellg(возврат позиции курсора в файл
и как это делать? по символьно читать файл и анализировать толи это что нам надо, а потом возвращать обратно на n считанных символов курсор? да не, это ужас.
К тому же емнип, если записываемый сектор будет больше того который был, то он еще и затрёт несколько символов другого (информация не переносится относительно)
xAtom
 Аватар для xAtom
910 / 735 / 60
Регистрация: 09.12.2010
Сообщений: 1,346
Записей в блоге: 1
01.10.2011, 20:10     "вставка" с "заменой" текста в файле. #4
Цитата Сообщение от Razzeeyy Посмотреть сообщение
мысль складывать всё содержимое файла в какой нибудь string buffer и уже по нему потом искать и с ним работать. а при завершении работы просто перезаписывать файл содержимым string buffer
Надо именно так делать, если конфиг-файл весил бы до 100MB то можно было просто работать с файлом, сам по себе файл не может сжиматься или расширяться только затирать старое значение пробелами или нулями любым символом, в итоге будут создаваться множество пустых фрагментов ну как в БД боряться с фрагментацией. Одно дело БД другое килобайтный конфиг-файл, вот пример набросал в начале весь конфигурационный файл считывается в карту map, уникальными ассоциативными ключами далее пример сохранения карты в конфиг с перезаписью всего файла. как и должно быть, не надо постоянно головку диска гонять если озу-память за 1GB переваливает, да и скорость работы диска на много медленнее озу.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <fstream>
#include <map>
#include <iostream>
#include <string>
using namespace std;
 
map<string, string> config;
 
int  main(void) {
 
    fstream  fp("D:\\config.txt", fstream::in); 
    if(! fp.is_open())
         exit(1);
 
    string line;
    char key[64], value[255];
    while(! fp.eof()) {
          getline(fp, line);
          if(sscanf(line.c_str(), "%[^ ]%*[^\"]\"%[^\"]\"", key, value) >= 2) 
                 config[key] = value;
     }
     fp.clear();
     fp.close();
 
      // вот так получать доступ по имени ключа
     cout << '\t' << config["section"].c_str() << endl;
     cout << '\t' << config["value1"].c_str()  << endl;
 
     // показать пары ключ = значение
     map<string, string>::iterator iter = config.begin();
     while(iter != config.end()) {
             cout << iter->first.c_str() << '\t' << iter->second.c_str() << endl;
             *iter++;
     }
 
     // записываем новые значения
    config["section"] = "MySQL and DB2";
    config["more"]    = "sub systems";
    config["value1"]  = "200";
    config["value2"]  = "7";
 
    // файл будет перезаписан
    fp.open("D:\\config.txt", fstream::out | fstream::trunc);
    for(iter = config.begin(); iter != config.end(); *iter++) {
          line = iter->first + " \"" + iter->second + "\"\n";
          fp.write(line.c_str(), line.length());
    }
    fp.flush();
    fp.close();
    config.clear();
    cin.get();
    return 0;
}
Razzeeyy
 Аватар для Razzeeyy
30 / 7 / 2
Регистрация: 01.03.2011
Сообщений: 95
01.10.2011, 22:48  [ТС]     "вставка" с "заменой" текста в файле. #5
xAtom, спасибо. но у меня там section отмечает имя секции поэтому у меня наверно будет общая карта map<string, map> и под карты (map<string, string>) с каждой секцией.
Цитата Сообщение от xAtom Посмотреть сообщение
"%[^ ]%*[^\"]\"%[^\"]\""
я вот только эту штуку непонял, это RegEx надо полагать?

а то я у себя вообще ужасным кодом вычленяю параметр и значение
-=ЮрА=-
Заблокирован
Автор FAQ
02.10.2011, 14:04     "вставка" с "заменой" текста в файле. #6
Razzeeyy, напишите конкретно что у вас в файле, что вам заменить и какой длинній заменяющий блок, ві задали общий вопрос, я вам дал общий ответ...
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.10.2011, 07:25     "вставка" с "заменой" текста в файле.
Еще ссылки по теме:

Переписать в файл О все элементы файла К с заменой в них символа "0" на символ "1" и наоборот C++
Переписать в файл О все элементы файла К с заменой в них символа "0" на символ "1" и наоборот C++
Классы "Фигура", "Прямоугольник", "Круг" C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
03.10.2011, 07:25     "вставка" с "заменой" текста в файле. #7
Цитата Сообщение от Razzeeyy
это RegEx надо полагать?
это не regexp, но это устроено проще

C89(draft) 4.9.6.2 fscanf
[ Matches a nonempty sequence of characters from a set of expected
characters (the scanset ). The corresponding argument shall be a
pointer to the initial character of an array large enough to accept
the sequence and a terminating null character, which will be added
automatically. The conversion specifier includes all subsequent
characters in the format string, up to and including the matching
right bracket ( ] ). The characters between the brackets (the
scanlist ) comprise the scanset, unless the character after the left
bracket is a circumflex ( ^ ), in which case the scanset contains all
characters that do not appear in the scanlist between the circumflex
and the right bracket. As a special case, if the conversion specifier
begins with [] or [^] , the right bracket character is in the scanlist
and the next right bracket character is the matching right bracket
that ends the specification. If a - character is in the scanlist and
is not the first, nor the second where the first character is a ^ ,
nor the last character, the behavior is implementation-defined.
Yandex
Объявления
03.10.2011, 07:25     "вставка" с "заменой" текста в файле.
Ответ Создать тему
Опции темы

Текущее время: 01:33. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru