Программа крашится после вызова метода

252
26 декабря 2017, 17:26

Суть программы в том, чтобы выводить поздравление, используя имена, праздники и пожелания, которые заданы в трех соответствующих файлах (на каждой строке - новые имя/праздник/пожелание). Так вот если сразу приступать к выводу имеющихся данных в файлах, то все работает, а если, например, ввести имя, а потом начать вывод с этим именем, то программа крашится. Помогите понять, почему. Место краша чуть ниже полоски равно, оттуда и стоит, я думаю, смотреть код.

Text.cpp:

#include "Text.h"
#include "conio.h"
#include <cstdlib>
#include <fstream>
#include <iostream>
using namespace std;
Sentence::Sentence()
{
}
Sentence::Sentence(const string & newText)
{
    convert(newText);
}
Sentence::~Sentence()
{
}
void Sentence::setText(const string & newText)
{
    sentence.clear();
    convert(newText);
}
void Sentence::convert(const string & newText)
{
    string temp;
    for (unsigned int i = 0; i < newText.size(); i++)
    {
        if (newText[i] == ' ')
        {
            sentence.push_back(temp);
            temp.clear();
        }
        else
            temp.push_back(newText[i]);
    }
    sentence.push_back(temp);
}
void Sentence::replaceKey(const string & key, const string & dataKey)
{
    for (unsigned int i = 0; i < sentence.size(); i++)
    {
        if (sentence[i] == key)
            sentence[i] = dataKey;
    }
}
string Sentence::getStr()
{
    string str;
    for (unsigned int i = 0; i < sentence.size(); i++)
    {
        str += sentence[i] + ' ';
    }
    str.pop_back();
    str.push_back('.');
    return str;
}
/*=====================================================================================================================*/
Generator::Generator()
{
    string m;
    system("cls");
    cout << "Выберите действие: " << endl;
    cout << "1.Добавить имя/праздник/поздравление в соответствующий файл." << endl;
    cout << "2.Продолжить работу с уже имеющимися данными." << endl;
    cin >> m;
    if (m == "1") generator();
    else if (m == "2") // Вот тут прога крашится, если я уже вводил данные в 1 пункте
    {
        loadData();
    }
    else Generator();
        pozdravlenie.push_back("Дорогой(-ая) $name$ , поздравляю Вас с праздником $prazdnik$ и желаю Вам $pozhelanie$ ");
        pozdravlenie.push_back("$name$ , желаю $pozhelanie$ в этот прекрасный $prazdnik$ ");
        pozdravlenie.push_back("Уважаемый(-ая) $name$ , хочу пожелать $pozhelanie$ в этот светлый праздник $prazdnik$ ");
        pozdravlenie.push_back("$name$ , имею честь желать Вам $pozhelanie$ в этот изумительный $prazdnik$ ");  
}
Generator::~Generator()
{
}
void Generator::generator()
{
    string p;
    system("chcp 1251");
    system("cls");
    cout << "Выберите действие: " << endl;
    cout << "1.Добавить имена в файл." << endl;
    cout << "2.Добавить праздники в файл." << endl;
    cout << "3.Добавить поздравления в файл." << endl;
    cout << "4.Вернуться назад." << endl;
    cin >> p;
    if (p == "1") generatorName();
    else if (p == "2") generatorPrazdnik();
    else if (p == "3") generatorPozhelanie();
    else if (p == "4") Generator();
    else generator();
}
void Generator::generatorName()
{
    string ln;
    string name;
    ofstream fileName;
    fileName.open("name.txt", ios_base::app);
    if (fileName.is_open())
    {
        while (true)
        {
            cout << "\nВведите имя: ";
            cin.get();
            getline(cin, name);
            fileName << name << endl;
            cout << "Ввести еще одно имя?\n 1. Да \n 2. Нет\n";
            cin >> ln;
            if (ln == "1")
            {
                generatorName();
                break;
            }
            if (ln == "2")
            {
                generator();
                fileName.close();
                break;
            }
        }
    }
    else
    {
        cout << "Файл name.txt не создан.\nСоздайте файл name.txt в каталоге с Programma Pozdravlenie.exe " << endl;
        exit(1);
    }
}
void Generator::generatorPrazdnik()
{
    string lp;
    string prazdnik;
    ofstream filePrazdnik;
    filePrazdnik.open("prazdnik.txt", ios_base::app);
    if (filePrazdnik.is_open())
    {
        while (true)
        {
            cout << "\nВведите праздник: ";
            cin.get();
            getline(cin, prazdnik);
            filePrazdnik << prazdnik << endl;
            cout << "Ввести еще один праздник?\n 1. Да \n 2. Нет\n";
            cin >> lp;
            if (lp == "1") 
            {
                generatorPrazdnik();
                break;
            }
            if (lp == "2")
            {
                generator();
                filePrazdnik.close();
                break;
            }
        }
    }
    else
    {
        cout << "Файл prazdnik.txt не создан.\nСоздайте файл prazdnik.txt в каталоге с Programma Pozdravlenie.exe " << endl;
        exit(1);
    }
}
void Generator::generatorPozhelanie()
{
    string lpz;
    string pozhelanie;
    ofstream filePozhelanie;
    filePozhelanie.open("pozhelanie.txt", ios_base::app);
    if (filePozhelanie.is_open())
    {
        while (true)
        {
            cout << "\nВведите пожелание: ";
            cin.get();
            getline(cin, pozhelanie);
            filePozhelanie << pozhelanie << endl;
            cout << "Ввести еще одно пожелание?\n 1. Да \n 2. Нет\n";
            cin >> lpz;
            if (lpz == "1")
            {
                generatorPrazdnik();
                break;
            }
            if (lpz == "2")
            {
                generator();
                filePozhelanie.close();
                break;
            }
        }
    }
    else
    {
        cout << "Файл pozhelanie.txt не создан.\nСоздайте файл name.txt в каталоге с Programma Pozdravlenie.exe " << endl;
        exit(1);
    }
}
string Generator::create()
{
    int index = rand() % pozdravlenie.size();
    static int i = 0;
    string str = pozdravlenie[index];
    sentence.setText(str);
    index = rand() % prazdnik.size();
    sentence.replaceKey("$prazdnik$", prazdnik[index]);
    index = rand() % pozhelanie.size();
    sentence.replaceKey("$pozhelanie$", pozhelanie[index]);
    if (i < name.size())
    {
        sentence.replaceKey("$name$", name[i++]);
        str = sentence.getStr();
    }
    else
    {
        str = "None";
    }
    return str;
}
void Generator::loadData()
{
    ifstream file("prazdnik.txt");
    string str;
    char* letter = new char[255];
    if (file.is_open())
    {
        while (true)
        {
            file.getline(letter, 255, '\n');
            if (file.eof()) break;
            str = letter;
            prazdnik.push_back(str);
        }
    }
    else
    {
        cout << "Файл prazdnik.txt не создан.\nСоздайте файл prazdnik.txt в каталоге с Programma Pozdravlenie.exe " << endl;
        exit(1);
    }
    file.close();
    file.open("pozhelanie.txt");
    if (file.is_open())
    {
        while (true)
        {
            file.getline(letter, 255, '\n');
            if (file.eof()) break;
            str = letter;
            pozhelanie.push_back(str);
        }
    }
    else
    {
        cout << "Файл pozhelanie.txt не создан.\nСоздайте файл pozhelanie.txt в каталоге с Programma Pozdravlenie.exe " << endl;
        exit(1);
    }
    file.close();
    file.open("name.txt");
    if (file.is_open())
    {
        while (true)
        {
            file.getline(letter, 255, '\n');
            if (file.eof()) break;
            str = letter;
            name.push_back(str);
        }
    }
    else 
    {
        cout << "Файл name.txt не создан.\nСоздайте файл с названием name.txt в каталоге с Programma Pozdravlenie.exe " << endl;    
        exit(1);
    }
    file.close();
    delete[] letter;
} 

Заголовочный файл Text.h:

#pragma once
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Sentence
{
public:
    Sentence();
    Sentence(const string & newSentence);
    ~Sentence();
    void setText(const string & newSentence);
    void replaceKey(const string & key, const string & dataKey);
    string getStr();
private:
    vector<string> sentence;
    void convert(const string & newSentence);
};

class Generator
{
public:
    Generator();
    ~Generator();
    string create();
    void generator();
    void generatorName();
    void generatorPrazdnik();
    void generatorPozhelanie();
private:
    void loadData();
private:
    Sentence sentence;
    vector<string> pozdravlenie;
    vector<string> name;
    vector<string> pozhelanie;
    vector<string> prazdnik;
};

Main.cpp:

#include "Text.h"
#include <iostream>
#include <cstdlib>
#include <locale>
#include <ctime>
#include <conio.h>
int main()
{
    setlocale(LC_ALL, "Russian");
    srand((unsigned int)time(NULL));
    Generator gen;
    string str;
    while ((str = gen.create()) != "None") 
        cout << str << endl;
    system("pause");
    return 0;
}
Answer 1

Если коротко, у Вас ошибка в методе Generator::loadData().

file.getline(letter, 255, '\n');
if (file.eof()) break; //<-- Вы выходите из цикла раньше, чем записываете результат чтения(в случае конца файла).
str = letter;
prazdnik.push_back(str);

Далее по коду есть такие ошибки, не буду приводить здесь.

READ ALSO
OSM отображение карты C++

OSM отображение карты C++

Каким образом можно отобразить OpenStreetMap карту средствами C++/Qt (БЕЗ QML)?

204
Реализация push_back для вектора

Реализация push_back для вектора

Мне нужно написать реализацию push_back для вектораНо я не знаю как правильно

239
Нахождение слов, у которых есть удвоение букв [требует правки]

Нахождение слов, у которых есть удвоение букв [требует правки]

ввести предложения и вывести на экран те его слова, в которых удвоение букв, или вывести сообщение об отсутствии таких словНельзя использовать...

185