[Из песочницы] Избитая банальность. Как школьник бота писал

Мне 16 и я школьник. Не так уж давно меня посетила идея написать бота… Нет, PHP-поделие, уныло висящее на никому не нужном сайте. И даже не бесполезный ответчик на фразы типа »! Погода».

Бот задумывался для развлечения как «говорилка» на десктоп. Ужасно, правда? Но мне хочется узнать свои ошибки, ведь я ни разу не показывал свой код кому-либо, в школе только паскаль. Итак, следуя ненавидимому некоторыми чистому структурному подходу я написал первоначальный вариант на C++.

Задумка такова. Бот берет фразу из консоли, вычленяет слова, проверяет каждое по словарю, расположенному в файле «Memory.txt», и возвращает найденный ответ к каждому слову; если ни на одно слово ответ не найден, то он возвращает оговоренную фразу (не принципиально).

Словарь в файле «Memory.txt» структурирован простейшим образом:
слово=ответ

Пример:
яблоко=яблоки вкусные

Bot.h- заголовочный файл, о нем позже. Основные функции будут располагаться в файле Bot.cpp:

/**
Даниил Демидко, 2015
Основные функции Cbot
*/
#include"Bot.h"

Определим имя для словаря в этом же файле:

///Имя тектового файла- памяти бота
const char *const MemoryPath="Memory.txt";

«Основа основ» бота — это функция, выделяющая слова из одной строки в массив строк и возвращающая указатель на массив.

const std: string *const GetWords (const std: string &Word)
    ///Количество возвращаемых слов в массиве-глобальная переменная, надеюсь всем понятно почему...
    int MaxIndex=0;
    ///Функция выделяет слова из строки
    const std::string *const GetWords(const std::string &Word)
    {
        ///Резервируется массив в куче на 256 слов
        std::string *const PtrWords=new std::string[256];
        ///Сбрасываем предидущее значение
        MaxIndex=0;
        ///Фиксирует наличие искомого символа в предидущих циклах
        bool Fix=false;
        ///Последний символ- служебный, поэтому не учитыватся
        for(int i=0; i


Следующая функция получает строку для поиска и ищет ее по словарю, если ответ не найден, возвращает пустую строку ». Хочу обратить внимание на то, что если слово будет найдено внутри другого слова в файле ассоциаций, то ответ будет засчитан.

const std: string GetAssociation (const std: string &Word)
///Функция возвращает ассоциацию
    const std::string GetAssociation(const std::string &Word)
    {
        std::ifstream Memory(MemoryPath, std::ios::in);
        if(!Memory)
        {
            std::ofstream NewMemory(MemoryPath);
            NewMemory.close();
            Memory.open(MemoryPath);
            return "";
        }
        while(!Memory.eof())
        {
            std::string Buffer="";
            std::getline(Memory, Buffer);
            if(Buffer.find(Word)!=-1)
            {
                std::string Result[2];
                for(int i=0, Index=0; i


В моем представлении структурный подход не отменяет инкапсуляцию, поэтому мы добавим анонимное пространство имен — для банальной инкапсуляции включающее в себя все предыдущие функции.

Таким образом предыдущие функции уже не будут доступны при подключении заголовочного файла «Bot.h». Позволю себе сослаться на гуру:

Это самый передовой способ избежать объявления функций и переменных со статическим связыванием.
Доступ может быть осуществлен только в рамках единицы
трансляции (т. е. в полученном после предварительной обработки файле),
в которой они находятся, точно так же, как к статическим переменным.
Стивен С. Дьюрхест, «C++. Священные знания»


Вот, все вместе:

namespace
namespace
{
    ///Имя тектового файла- памяти бота
    const char *const MemoryPath="Memory.txt";
    ///Количество возвращаемых слов в массиве
    int MaxIndex=0;
    ///Функция выделяет слова из строки
    const std::string *const GetWords(const std::string &Word)
    {
        ///Резервируется массив на 256 слов
        std::string *const PtrWords=new std::string[256];
        ///Сбрасываем предидущее значение
        MaxIndex=0;
        ///Фиксирует наличие искомого символа в предидущих циклах
        bool Fix=false;
        ///Последний символ- служебный, поэтому не учитыватся
        for(int i=0; i

А теперь подведем итог — файл «Bot.cpp» полностью:

Bot.cpp
/**
Даниил Демидко, 2015
Основные функции Cbot
*/
#include"Bot.h"
///Анонимное пространство имен инкапсулирует функции за пределами этой единицы компиляции
namespace
{
    ///Имя тектового файла- памяти бота
    const char *const MemoryPath="Memory.txt";
    ///Количество возвращаемых слов в массиве
    int MaxIndex=0;
    ///Функция выделяет слова из строки
    const std::string *const GetWords(const std::string &Word)
    {
        ///Резервируется массив на 256 слов
        std::string *const PtrWords=new std::string[256];
        ///Сбрасываем предидущее значение
        MaxIndex=0;
        ///Фиксирует наличие искомого символа в предидущих циклах
        bool Fix=false;
        ///Последний символ- служебный, поэтому не учитыватся
        for(int i=0; i

Вот и все с файлом «Bot.cpp» мы закончили, теперь быстро набросаем заголовочный файл «Bot.h»:

Bot.h
#ifndef BOT
#define BOT
///На всякий случай проверяем, подключен ли уже iostream
#ifndef _GLIBCXX_IOSTREAM
#include
#endif            //_GLIBCXX_IOSTREAM
///Проверяем fstream
#ifndef _GLIBCXX_FSTREAM
#include
#endif           //_GLIBCXX_FSTREAM
///Наша уже описанная функция для связи с миром
extern const std::string GetFullAssociation(const std::string&);
#endif          //BOT


С основной частью мы закончили, дело за малостью — функцией main (). Она у нас будет располагаться в файле Cbot.cpp. Cbot — звучит невероятно оригинально, ведь правда?

Cbot.cpp
#include"Bot.h"
int main()
{
    ///Файл кодировки 866 OEM (русская), файл "Memory.txt" должен быть в ней же
    setlocale(LC_ALL, ".866");
    std::wcout<<"Cbot 2.0\nАвтор: Даниил Демидко\nE-Mail: DDemidko1@gmail.com"<

Все, бот готов, собираем вместе, получаем Cbot.exe, сохраняем файл Memory.txt в кодировке OEM 866 и кладем в одну директорию программой. Ссылка на сборку: spaces.ru/files/? r=main/view&Read=58688510

Ожидаю конструктивный поток критики показывающий на очевидные ошибки в коде.

© Habrahabr.ru