Написать / прочитать структуру для файла с использованием функций, Visual C ++ 2008 Express
-
12-12-2019 - |
Вопрос
Я сделал три файла, используя 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)
.
было гораздо лучшей идеей.Я считаю, что если вы объедините их, вы окажетесь без ошибки.
Если ошибка продолжается, пожалуйста, используйте отладчик и вставьте строку.Кроме того, я могу предоставить образец кода, который я описал, если вы хотите.