TextParser
21.07.2014, 21:05

Скачать исходники

Это класс для разбора текстового файла вида:
Name1 
Name2 = "TextValue" 
Name3=123.2

Также строка игнорируется, если она начинается со знака ";".
Класс сам определяет тип значения (справа от знака равно), причем можно добавлять свои типы. Вот его заголовочный файл (только существенные моменты):
#pragma once
 #include <STRING>
 #include <FSTREAM>
 #include <ios>
 using std::string;
 using std::fstream;
 using std::ios;

/*-------------------------------------
 Считаем, что файл может выглядить так:
 ; Комментарий
 Name1 = "11111" 
   ; Комментарий
   Name2=123.44
 Name3= 111
 Name4
    Name5 ="1111"
 ---------------------------------------*/

 #define ERR_OPENFILE             1
 #define ERR_TYPE                 2
 #define ERR_NOTCREATE            3
 #define ERR_ENDOFFILE            4

 // Тип значения строки
 enum StringType
 {
    SD_BASE      = -2,
    ST_ERROR   = -1,        // Невозможно определить тип значения
    ST_NAMEONLY = 0,        // нет значения, есть только название
    ST_STRING   = 1,        // Значение - строка
    ST_INT      = 2,        // Значение - целое число
    ST_FLOAT   = 3          // Значение - дробное число
 };

 enum OpenType             // Тип открытого парсера
 {
    OT_NONE = 0,
    OT_READ,
    OT_WRITE
 };

 // Структура для заполнения значением строки
 class StringData
 {
 public:
    string Name;            // Название значения
    StringType Type;        // Тип значения

    // Заполняется одно из этих полей в зависимости от Type
    string strVal;
    int intVal;
    double fVal;
    virtual StringType GetType() { return SD_BASE; };      // Чтобы можно было различать типы
    ...
 };

 class CTextParser
 {
 '''public:
 protected:'''
    ...

    '''// Чтобы можно было потом добавить еще новые типы
    // Функция возвращает true, если тип узнала'''
    virtual bool CustomType(string str, StringData *info) { return false; };

    unsigned int m_CurLine;        // Текущая строка
    ...

 public:
    CTextParser();
    virtual ~CTextParser();

    OpenType Create(const char *fname, bool Write, bool Overwrite = false);   // С этого надо начинать
    void Destroy();                                       // А этим кончать (но не обязательно)
    bool GetNextValue(StringData *info);                  // Получить следующую строку (пустые строки пропускает)

    // Функции для записи в файл
    bool Write (string name, string val);
    bool Write (string name, int val);
    bool Write (string name, float val);
    bool Write (string name, double val);
    bool Write (StringData *info);
    bool WriteComment(string str);

    ...
}

 
Парсер может как читать файл, так и писать в него. Чтобы воспользоваться TextParser, надо создать его экземпляр и вызвать метод Create(). Первый параметр - это имя файла, с которым хотим работать, дальше идет переменная типа bool, которая равна true, если мы хотим писать в файл, и false, если надо обработать файл, то есть пропарсить. А последний параметр указывает надо ли перезаписывать файл при открытии на запись, если файл с таким именем уже существует. Метод возвращает тип OpenType, которые обозначает, как открыли файл, на чтение, на запить, или открыть файл не удалось (тогда возвращается значение OT_NONE.
Вся суть класса заключена в методе GetNextValue. Он возвращает true, если разбор очередной строки прошел удачно, и false в противном случае (возможно файл закончился). Также этот метод заполняет класс типа StringData, который используется как структура. Он объявлен следующим образом:
// Структура для заполнения значением строки
 class StringData
 {
 public:
    string Name;               // Название значения
    StringType Type;           // Тип значения

    // Заполняется одно из этих полей в зависимости от Type
    string strVal;
    int intVal;
    double fVal;
    virtual StringType GetType() { return SD_BASE; };      // Чтобы можно было различать типы
    ...
 };

 
Этот класс содержит только открымые метода и члены. Член Name содержит имя параметра (то, что стоит слева от знака равно). Член Type определяет тип значения. В исходном варианте (просто класс можно расширять) может принимать следующие значения:
enum StringType
 {
    SD_BASE     = -2,                                   
    ST_ERROR    = -1,      // Невозможно определить тип значения
    ST_NAMEONLY = 0,       // нет значения, есть только название
    ST_STRING   = 1,       // Значение - строка
    ST_INT      = 2,       // Значение - целое число
    ST_FLOAT    = 3        // Значение - дробное число
 };

 
Ну а с функциями Write там и так все понятно, для их использования надо открыть файл, естественно, на запись.
После использоваться надо вызвать метод Destroy(), но это не обязательно (если только вы не захотите работать с другим файлом), он вызывается в деструкторе.
Класс можно расширять, т.е. добавлять типы, которые изначально не могут быть распознаны. Для этого есть виртуальная функция bool CustomType(string str, StringData *info), которая вызывается каждый раз, когда класс не может распознать тип. Она должна возвратить true, если ей удалось узнать тип, и false в противном случае. Т.о. для того, чтобы добавить новый тип, надо:
В производном классе переопределить функцию CustomType
Сделать потомка от StringData, в который добавить новое поле и флаг, соответствующие новому типу
Вот пример того, как я это сделал для распознавания цветов, которые записаны в виде ARGB (например, 255, 0, 157, 46):
#include "..\PARSER\TextParser.h"

 #define SD_GUITEXTDATA   2

// Означает, что распознанное значение - цвет
 #define ST_COLOR      4               

 // Класс для заполнения парсером - добавился цвет
 class CGuiTextData : public StringData
 {
 public:
    D3DCOLOR Color;
    virtual int GetType()  { return SD_GUITEXTDATA; };
 };

 class CGuiTextParser : public CTextParser  
 {
 public:
    CGuiTextParser();
    virtual ~CGuiTextParser();
    virtual bool CustomType(string str, StringData *info);      // Будет пытаться распознать цвет
 };

Просмотров: 592 | Загрузок: 0 | Рейтинг: 5.0/1
X
Ссылка:
BB-код:
HTML-код:
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
%