Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблемы с парсингом 
:(
    Опции темы
MrImho
Дата 1.11.2009, 00:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 31.7.2009

Репутация: нет
Всего: нет



Здравствуйте. Недавно стал изучать программирование. И вот стал вопрос о создании системы диалогов как в Gothic или Risen. Я убрал все функции рендера оставив только консольную программу чисто реализующую эту функции. Что она должна делать: Парсить текстовый файл вида (извеняюсь за английский плохо знаю):
Имя файла "test", содержание:
Код

1|0:How do you do?@I am fine, sank you->1@Bad->2@Very bad->3@End->4
1|1:It's good. Ok go to the castle.@End->4
1|4:f-end
2|0:Hello I am weapon trader, my blade is very good, please see@Ti sam delaesh mechi?->1@Pokaji svoy tovar->2@End->3
2|3:f-end

Где первое число до "|" идентификатор персонажа, число после "|" и до ":" идентификатор текста диалога данного персонажа. Дальше первая его фраза до "@", а после возможные ответы до "->" после и до "@" идентификатор текста диалога данного персонажа. Если перед текстом стоит "f-" то надо запустить функцию с последующим названием.
Вот что сейчас мне удалось сделать:
Код

fstream input("test");
string temp;
int i;
string a,b;
while (getline(input, temp))
{
    if (temp.substr(0, 4) == "2|0:")
    {
    a=temp.c_str() + 4;
    i=a.find("@");
    a = temp.substr(4, i);
    //b = temp.c_str()+i+1;
    cout << a << endl;
    break;
    }
}

Этот код выводит первые слова персонажа с идентификатором 2, как сделать чтобы, он посчитал кол-во ответов и вывел их на экран:
1 - первый ответ
2 - второй ответ
3 - третий ответ
И пользователь нажав цифру 3 и enter заставил бы выполнится функцию end(), т.к. в исходном файле написано: 2|3:f-end
Честно, мне в голову ничего не приходит, опыта программирования в c++ маловато. Буду признателен, тому кто поможет.


Это сообщение отредактировал(а) MrImho - 1.11.2009, 00:49
PM MAIL   Вверх
andrew_121
Дата 1.11.2009, 00:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



MrImho
1. Опиши структуру которая и будет представлять распарсенную строку.
2. Распарсь строку и помести результат в структуру.
3. все остальные действия.


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
sdukshis
Дата 1.11.2009, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 92
Регистрация: 23.3.2009

Репутация: нет
Всего: 1



Могу предложить ответ на вопрос о вызове функции.
Если я правильно понял, то задача заключается в том, чтобы имея строковое представление имени функции вызвать ее.

Преложенное мной решение основано на использовании динамического полиморфизма для классов-функторов совместно с отображением контейнера map.

Если моё решение покажется кому-нибудь слишком сложным, то очень прошу подсказать возможность сделать это попроще (без switch  smile )
Код

#include <iostream>
#include <map>
#include <string>

using namespace std;

// Интерфейс для класса-функтора
class Functor_Interface{
public:
    Functor_Interface() {};
    // Не забываем про виртуальный деструктор в базовых классах
    virtual ~Functor_Interface() {};
    virtual void exec() const = 0; // Для выполнения каких-либо действий будем перегружать exec
    // можно определить и operator(), но его не удобно вызывать для указателя на класс.
};


// Ниже приведены 2 наследника с различными перегрузками exec()

class SaySomething :public Functor_Interface{
public:
    virtual void exec() const {
        wcout << L"Say something" << L"\n";
    }
};

class DoSomething :public Functor_Interface{
public:
    virtual void exec() const {
        wcout << L"Do something" << L"\n";
    }
};

// Для отображения строки в объект будет использовать std::map
typedef map<string, Functor_Interface* >  Actions;

int main(){
    // Создаем отображение для действий
    Actions A;

    // Добавляем 2 действия
    A["say"] = new SaySomething;
    A["do"]  = new DoSomething();

    string str = "say";
    // Вызываем действие say
    A[str]->exec();

    str = "do";

    //Вызываем действие do
    A[str]->exec();

    // Не забываем удалять память (если лень, то можно использовать boost::shared_ptr)
    delete A["say"];
    delete A["do"];

    return 0;
}



Это сообщение отредактировал(а) sdukshis - 1.11.2009, 16:29
PM MAIL   Вверх
MrImho
Дата 2.11.2009, 02:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 31.7.2009

Репутация: нет
Всего: нет



sdukshis Да Вы правы я даже не представлял как вызвать функцию имея её имя. ООП в с++ я плохо знаю, но понял что Вы имели ввиду благодарю за помощь. И если Вас не затруднит не могли бы Вы пояснить назначение строки:
Код

typedef map<string, Functor_Interface* >  Actions;

Вот как я понял эту строку: Мы задаём новый класс переменной map, эта переменная строковая, использует класс Functor_Interface и этот класс переменной называется Actions. Эта строка как я понял использует шаблон (template). Шаблоны так и остались для меня загадкой, прочитал несколько книг по с++, но так и не "въехал" для чего они. Правда книги на английском читал, который плохо знаю. В 2 словах можете про них рассказать? Просто я не хочу в слепую использовать Ваш код, а хочу понять, как работает, чтобы в будущем не возникало вопросов.

50% задачи решена.

Теперь остался парсинг (я его тоже плохо делаю, ведь я только недавно окунулся в мир прикладного программирования)
andrew_121 Вы не могли бы подсказать какая функция считает вхождения символа в строке? Мне нужно узнать кол-во знаков "@" и циклом выполнить операцию. Если Вас не затруднит, Вы можете дать список основных функций, которые парсят текст. Я тогда смогу попробовать написать уже конечную программу, с парсингом и запуском нужных функций.

Спасибо всем кто откликнулся, особая благодарность sdukshis я Вам рейтинг поднял (наверху на 3 звёздочку килкнул - думаю "это есть хорошо", здесь на форуме smile ).
PM MAIL   Вверх
sdukshis
Дата 3.11.2009, 00:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 92
Регистрация: 23.3.2009

Репутация: нет
Всего: 1




Цитата

И если Вас не затруднит не могли бы Вы пояснить назначение строки:
Код

typedef map<string, Functor_Interface* >  Actions;


Объявление нового типа Actions (просто везде вставлять конструкцию map<string, Functor_Interface* > на мой взгляд некрасиво)
Цитата

В 2 словах можете про них рассказать?

Если действительно в 2-х словах то шаблоны это полиморфизм времени компиляции, но что бы нормально понять эту фразу надо побольше о них почитать (например у Страуструпа в книге "Дизайн и эволюция С++")



Это сообщение отредактировал(а) sdukshis - 3.11.2009, 00:44
PM MAIL   Вверх
MrImho
Дата 3.11.2009, 23:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 31.7.2009

Репутация: нет
Всего: нет



sdukshis Благодарю за разъяснение и за название книжки, поищу и скачаю.
Но вот с парсингом ни как не разберусь, вообщем не нашёл функции поиска символа, поэтому сделал свою, вот что сейчас имеется:
Код

#include <iostream.h>
#include <fstream>
using namespace std;
int find_ch(string str,char* chr,int j)
{
int i;
string a,b;
i=str.find(chr);
b=str.c_str()+i+1;
    if(i!=-1)
    {
    j=j+1;
    j=find_ch(b,chr,j);
    }
return j;
}
int main()
{
fstream input("file_name");
string temp,main_dlg,next_dlg,dd;//обратите внимание на переменную dd она нигде не используется, но если её не объявить функция find_ch работает некоректно, незнаю почему, может кто объяснит
int i,count_ch,d;
while (getline(input, temp))
{
    if (temp.substr(0, 4) == "1|0:")
    {
    main_dlg=temp.c_str() + 4;
    i=main_dlg.find("@");
    main_dlg = temp.substr(4, i);
    next_dlg = temp.c_str()+i+4;
    count_ch=find_ch(next_dlg,"@",count_ch);
        /*for(i=1;i<=c;i++)
        {
        d=b.find("@");
        b=dd.substr(1,d);
        cout << "--------------------\n" << b << endl;
        }*/
        cout  << count_ch ;
    }
}
input.close();
system("PAUSE");
return 0;
}

Но тут происходит непонятная вещь, если не объявлять переменную dd то число символов показывает постоянно разное (что-то вроде 345456 или 5467567).
Что за чудо не знаю.
И когда у меня есть кол-во ответов, не получается их вывести, просто я запутался если честно (даже стыдно об это говорить, на таком элементарном и запутался).
Если кто поможет буду благодарен.
PM MAIL   Вверх
just_geek
Дата 4.11.2009, 01:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 309
Регистрация: 13.12.2007

Репутация: 2
Всего: 10



Цитата

Но тут происходит непонятная вещь, если не объявлять переменную dd то число символов показывает постоянно разное (что-то вроде 345456 или 5467567).
Что за чудо не знаю.
И когда у меня есть кол-во ответов, не получается их вывести, просто я запутался если честно (даже стыдно об это говорить, на таком элементарном и запутался).
Если кто поможет буду благодарен.

А ты не пробовал, все целочисленные переменные после объявления иницализировать ?
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0811 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.