Написать / прочитать структуру для файла с использованием функций, Visual C ++ 2008 Express

StackOverflow https://stackoverflow.com//questions/10669513

Вопрос

Я сделал три файла, используя Visual C ++ 2008 Express для текстовой игры RPG. Прежде чем я действительно погрузился во все это, я хочу получить основные основы, вытянутые: Новая игра, Сохранить игру, продолжить игру, бросить игру. Пока у меня есть раздел «Сделать персонаж» (в этом случае найдут оружие) и бросить игру все вытянуты. Я застрял, как пройти статистику оружия из структуры в файл сохранения. Я, кажется, передаю членам структуры без выпуска и проверяйте файл, чтобы найти «мусор»: ì и -858993460 вместо моих ценностей.

Как я должен пойти на фиксацию функций save_game и indeation_game? Я сделал много исследований, пытаясь понять это, и ничто не пыталось, кажется, поможет.

Вот важные кусочки кода:

struct player_character
{
char type;
int damage;
int stability;
};

void save_game(player_character& pc, ofstream &save);
void continue_game(player_character& pc, ifstream &get);

int main()
{   
player_character pc;
ofstream save;
ifstream get;

//rest of main() goes here.

//pause screen
system("pause");
return 0;
}

//rest of functions go here.

void save_game(player_character &pc, ofstream &save_data) 
{
save_data.open  ("save.dat", ios::binary);
    if (save_data.is_open())
    {
    save_data << "pc.type = " << pc.type << endl;
    save_data << "pc.damage = " << pc.damage << endl;
    save_data << "pc.stability = " << pc.stability << endl;
                //doesn't work
    //save_data.write(reinterpret_cast<char*>(&pc), sizeof(pc));
    save_data.close();
    }
    else
    {
    cout << " Error. Unable to open file.";
    }
}

void continue_game(player_character &pc, ifstream &get_data) 
{
get_data.open("save.dat");
if (get_data.is_open())
    {
                //doesn't work
    //get.read(reinterpret_cast<char*>(&pc), sizeof(pc));
    get.close();
    }
    else
    {
    cout << " Error. Unable to open file.";
    }
}
.


Спасибо за ответ. Я пробую следующие изменения. Функция Prostrue_Game отображается для работы. Я не получаю ошибок (пока). Когда я выбираю сохранение После создания символа, я получает следующую ошибку: необработанный исключение на 0x69197A28 в Undone.exe: 0xC0000005: Доступ к нарушению чтения 1xFFFFFCCC.

Google показывает это как какой-то проблема Windows.

Почему моя функция вызывает эту ошибку?

void save_game(ofstream &save, player_character const &pc) 
{
save.open  ("save.dat");
    if (save.is_open())
    {
    save.write(reinterpret_cast<char const *>(pc.type), sizeof pc.type); 
    save.write(reinterpret_cast<char const *>(pc.damage), sizeof pc.damage); 
    save.write(reinterpret_cast<char const *>(pc.stability), sizeof pc.stability); 
    save.close();
    }
    else
    {
    cout << " Error. Unable to open file.";
    }
}

int continue_game(ifstream &get) 
{
if (!get.read(reinterpret_cast<char *>(&pc.type), sizeof pc.type)) { /* error */ } 
if (!get.read(reinterpret_cast<char *>(&pc.damage), sizeof pc.damage)) { /* error */ } 
if (!get.read(reinterpret_cast<char *>(&pc.stability), sizeof pc.stability)) { /* error */ } 

return pc.type;
return pc.damage;
return pc.stability;
}
.


Я изменил код save_game и indeation_game и включал его здесь. Я также собрал отладчик и вывод AutoS (небольшая версия AUTOS, не все семь страниц). По-видимому, мои значения не оцениваются в Save_Game, поэтому interny_Game не имеет ничего для работы и не вызывает ошибок.

Вот код и отладчик / Autos Pettouts:

int save_game(ofstream &save, player_character& pc) 
{
save.open  ("save.dat", ios::binary);
if (save.is_open())
{
//the error hits here:
    save.write(reinterpret_cast<char const *>(pc.type), sizeof pc.type); 
    save.write(reinterpret_cast<char const *>(pc.damage), sizeof pc.damage); 
    save.write(reinterpret_cast<char const *>(pc.stability), sizeof pc.stability); 
    save.close();
}
else
{
    cout << " Error. Unable to open file.";
}
return pc.type;
return pc.damage;
return pc.stability;
}

int continue_game(ifstream &get, player_character& pc)
{
get.open  ("save.dat", ios::binary);
if (get.is_open())
{
    if (!get.read(reinterpret_cast<char *>(&pc.type), sizeof pc.type)) { /* error */ } 
    if (!get.read(reinterpret_cast<char *>(&pc.damage), sizeof pc.damage)) { /* error */ } 
    if (!get.read(reinterpret_cast<char *>(&pc.stability), sizeof pc.stability)) { /* error */ } 
    get.close();
}
else
{
    cout << " Error. Unable to open file.";
}
return pc.type;
return pc.damage;
return pc.stability;
}
.

Отладчик Выходное окно: Исключение первого шанса на 0x644E7A28 в Undone.exe: 0xC0000005: Доступ к нарушению чтения Местоположение 0xFFFFFFCC. Необработанное исключение на 0x644e7A28 в Undone.exe: 0xc0000005: местоположение на нарушение доступа 1xFFFFFFCC.

Autos: - ПК {Type= '' Ущерб= -858993460 Стабильность= -858993460} Player_Character & тип -52 '' char Ущерб -858993460 int. Стабильность -858993460 int. pc.type -52 'ì' char - Сохранить {_filebuffer= {...}} std :: basic_ofstream> & + std :: basic_ostream> {...} std :: basic_ostream> + _Filebuffer {_pcvt= 0x00000000 _mychar= 'ì' _wrotesome= false ...} std :: basic_filebuf>


хорошо, я удалось добиться некоторого прогресса. Я обнаружил, что мне нужно было разместить аргументы в мою функцию main_menu (разумейте, что я не принимаю о главной функции (), но один, который я сделал), чтобы они были переданы на функцию Save_Game. Я также смог остановить ошибку доступа, добавив и в мою функцию записи. Так что это:

save.write(reinterpret_cast<char const *>(&pc.type), sizeof pc.type); 
save.write(reinterpret_cast<char const *>(&pc.damage), sizeof pc.damage); 
save.write(reinterpret_cast<char const *>(&pc.stability), sizeof pc.stability); 
.

вместо:

save.write(reinterpret_cast<char const *>(pc.type), sizeof pc.type); 
save.write(reinterpret_cast<char const *>(pc.damage), sizeof pc.damage); 
save.write(reinterpret_cast<char const *>(pc.stability), sizeof pc.stability); 
.

Код SAVVE_GAME до сих пор не работает должным образом, когда речь идет о том, чтобы поместить данные в файл, но он делает распечатка на экран.

Это было полезно?

Решение 3

Похоже, я понял это!Вот что я придумал: структура в массиве ... и кажется, работает просто хорошо.

void save_game(fstream& file, player_type& pc)
{
    file.open("save.dat");
    if (file.is_open())
        for (int i = 0; i < 1; i++)
        {
            file << pc.w_name << endl;
            file << pc.d_rate << endl;
            file << pc.s_rate << endl;
            file.close();
        }
        else
            cout << " Error. Unable to open file.";
    menu(pc);
}//end save function

void continue_game(fstream& file, player_type player[])
{
    file.open("save.dat");
    if (file.is_open())
        for (int i = 0; i < 1; i++)
        {
            file >> player[i].w_name;
            file >> player[i].d_rate;
            file >> player[i].s_rate;
            file.close();
        }                   
        else
            cout << " Error. Unable to open file.";
    for (int i = 0; i < 1; i++)
    {
        cout << "You are continuing the game with the following weapon: " << player[i].w_name << endl;
        cout << "Which has a damage rating of " << player[i].d_rate << " and a stability rating of " << player[i].s_rate << endl; 
    }
    cout << endl;
    menu(pc);
}//end continue_game
.

Другие советы

Вы должны прочитать и писать каждый примитивный тип данных, один за другим и использовать только неформатированный ввод / вывод.Пример:

void serialize(std::ostream & o, Player const & p)
{
    o.write(reinterpret_cast<char const *>(p.type), sizeof p.type);
    o.write(reinterpret_cast<char const *>(p.damage), sizeof p.damage);
    o.write(reinterpret_cast<char const *>(p.stability), sizeof p.stability);
}

Player deserialize(std::istream & i)
{
    Player p;
    char pt;
    int pd, ps;

    if (!i.read(reinterpret_cast<char *>(&pt), sizeof pt)) { /* error */ }
    if (!i.read(reinterpret_cast<char *>(&pd), sizeof pd)) { /* error */ }
    if (!i.read(reinterpret_cast<char *>(&ps), sizeof ps)) { /* error */ }

    p.type = pt; p.damage = pd; p.stability = ps;
    return p;
}
.

Последующие до предыдущего ответа и отредактированного вопроса.

Судя по подписи вашей продолжения_game,

int continue_game(ifstream &get)
.

ПК должен быть некоторая форма глобальной структуры, которая удерживает персонажа, который вы пытаетесь возобновить.Если ПК выделен во время выполнения, то вы используете его неправильно.

Когда вы делаете это:

    return pc.type;
    return pc.damage;
    return pc.stability;
.

Функция может иметь только один возвратный тип;Только PC.Type будет возвращен.Это не причина ошибки, а скорее дизайн, который вы должны знать.

Ваш начальный подход к innation_game, в котором вы проходили в соответствующей структуре в качестве параметра,

void continue_game(player_character &pc, ifstream &get_data) 
.

было гораздо лучшей идеей.Я считаю, что если вы объедините их, вы окажетесь без ошибки.

Если ошибка продолжается, пожалуйста, используйте отладчик и вставьте строку.Кроме того, я могу предоставить образец кода, который я описал, если вы хотите.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top