我的代码没有覆盖文本文件,即使它应该覆盖?
My code isn't overwriting the text file, even though it should be?
我们用 C++ 编写了非常相似的代码类型 class 但我的版本运行不正常,尽管它逐行(几乎)相同。
我的代码旨在保存用户的口袋妖怪,他们可以随意添加和删除。我的显示功能有效,但我的添加和删除功能无效。所有文件都在打开,但它并没有像预期的那样覆盖文件。真的不知道该怎么做,我是一个初学者,我知道的不多。
这是我目前得到的:
string name[100];
string type[100];
int level[100];
string newPokemon;
string newType;
int newLevel;
ifstream fin;
ofstream fout;
int numberOfPokemon = 0;
//Input Pokemon Info
cout << "Name of Pokemon: ";
getline(cin, newPokemon);
cin.ignore(100, '\n');
cout << "Pokemon type: ";
getline(cin, newType);
cin.ignore(100, '\n');
cout << "Pokemon level: "; //weird gap between "Pokemon type" and "pokemon level". I have to press enter twice from "pokemon type" to get to "pokemon level"
cin >> newLevel;
cin.ignore(5, '\n');
fin.open("pokemon.txt");
//Put file in array
if (fin.is_open())
{
while (isalnum(fin.peek()) && numberOfPokemon < 100)
{
getline(fin, name[numberOfPokemon]);
getline(fin, type[numberOfPokemon]);
fin >> level[numberOfPokemon];
fin.ignore(100, '\n');
if (name[numberOfPokemon] != newPokemon)
numberOfPokemon++;
}
fin.close();
}
//Output file
fout.open("pokemon.txt");
if (fout.is_open())
{
for (int i = 0; i < numberOfPokemon; i++)
{
fout << name[i] << "\n";
fout << type[i] << "\n";
fout << level[i] << "\n";
}
//Tack on new piece
fout << newPokemon << "\n";
fout << newType << "\n";
fout << newLevel << "\n";
fout.close();
cout << "Add Successful\n";
}
else
{
cout << "Add Failure\n";
}
现在是我的删除功能:
string name[100];
string type[100];
int level[100];
int pokemonCount = 0;
string deletedPokemon = "";
bool found = false;
ifstream fin;
cout << "Which Pokemon would you like to delete?" << endl;
getline(cin, deletedPokemon);
cin.ignore(5, '\n');
fin.open("pokemon.txt");
if (fin.is_open())
{
while (isalnum(fin.peek()))
{
getline(fin, name[pokemonCount]);
getline(fin, type[pokemonCount]);
fin >> level[pokemonCount];
fin.clear();
fin.ignore(100, '\n');
if (deletedPokemon == name[pokemonCount])
{
pokemonCount--;
found = true;
}
pokemonCount++;
}
fin.close();
cout << "ya the file opened" << endl; //always appears
}
ofstream fout;
fout.open("pokemon.txt");
if (fout.is_open())
{
for (int i = 0; i < pokemonCount; i++)
{
fout << name[i] << "\n";
fout << type[i] << "\n";
fout << level[i] << endl;
}
fout.close();
cout << "pokemon removed\n";
cout << "the file opened."; //it is returning that the file opened in both occasions in this function but nothing is happening!
}
else
{
cout << "removal failure";
cout << "The file didn't open";
}
return found;
在此功能结束时(如果我选择删除一个),它会提供 "Would you like to add a Pokemon?" 但它不会让我输入答案,它只会结束程序。
ofstream::open
的默认行为是简单地打开文件进行读写。如果你想覆盖文件,你需要在调用 open
.
时指定它
fout.open("pokemon.txt", ios_base::in|ios_base::out|ios_base::trunc);
确保您的文件未在属性下标记为只读。
此外,您的删除功能有一个错误:
bfound 应替换为 nDelete pokemon,当您写出文件时:
if (deletedPokemon == name[pokemonCount])
{
pokemonCount--;
found = true;
nDeleteIndex = i;
}
....
for (int i = 0; i < pokemonCount; i++)
{
if(i == nDeleteIndex)
continue;
fout << name[i] << "\n";
fout << type[i] << "\n";
fout << level[i] << endl;
}
现在它会重写你所有的口袋妖怪,而不会跳过你想删除的那个!
此外,如果用户有 155 个宠物小精灵作为完整索引,会发生什么情况。您要使用:
std::vector<string> names;
....
string szPokemon;
getline(fin, name[numberOfPokemon]);
names.push_back(szPokemon);
因此您不再有限制!
这是更简洁的代码,它更易于维护,每当你 add/remove 来自口袋妖怪的字段(闪亮?Male/Female?独特?)你将能够轻松地在CPokemonObject 而不是必须复制粘贴代码 100 次。
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
#define POKEMON_FILE "Pokemon.txt"
class CPokemon
{
public:
string szName;
string szType;
int nLevel;
CPokemon() : szName("Pika"), nLevel(10), szType("Lightning")
{};
void Read(ifstream &file)
{
file >> szName;
file >> szType;
file >> nLevel;
};
void Write(ofstream &file)
{
file << szName << endl;
file << szType << endl;
file << nLevel << endl;
};
void CreatePokemon()
{
//Input Pokemon Info
cout << "Name of Pokemon: ";
getline(cin, szName);
cout << "Pokemon type: ";
getline(cin, szType);
cout << "Pokemon level: "; //weird gap between "Pokemon type" and "pokemon level". I have to press enter twice from "pokemon type" to get to "pokemon level"
cin >> nLevel;
}
};
void WritePokemons(vector<CPokemon>& Pokemons)
{
ofstream fout;
fout.open(POKEMON_FILE);
//check the file open
if (!fout.is_open())
{
cout << "removal failure";
cout << "The file didn't open";
return;
}
//Write out all the pokemons
for (unsigned int i = 0; i < Pokemons.size(); i++)
Pokemons[i].Write(fout);
fout.close();
}
void ReadPokemons(vector<CPokemon>& Pokemons)
{
ifstream fin;
fin.open(POKEMON_FILE);
if (fin.is_open())
{
while (isalnum(fin.peek()))
{
CPokemon Pokemon;
Pokemon.Read(fin);
Pokemons.push_back(Pokemon);
}
fin.close();
cout << "ya the file opened" << endl; //always appears
}
}
bool DeletePokemon()
{
vector<CPokemon> Pokemons;
string szPokemonToDelete = "";
cout << "Which Pokemon would you like to delete?" << endl;
cin >> szPokemonToDelete;
//Read all pokemons
ReadPokemons(Pokemons);
ofstream fout;
fout.open("pokemon.txt");
//check the file open
if (!fout.is_open())
{
cout << "removal failure";
cout << "The file didn't open";
return false;
}
bool bFound = false;
for (unsigned int i = 0; i < Pokemons.size(); i++)
{
//Skip the pokemon to delete
if(Pokemons[i].szName == szPokemonToDelete)
{
bFound = true; //we found the pokemon to delete
continue;
}
Pokemons[i].Write(fout);
}
fout.close();
return bFound;
}
void AddPokemon()
{
vector<CPokemon> Pokemons;
//Read all pokemons from the file
ReadPokemons(Pokemons);
//Create the new porkemon
CPokemon Pokemon;
Pokemon.CreatePokemon();
//Add the pokemon to the list
Pokemons.push_back(Pokemon);
//Output file
WritePokemons(Pokemons);
}
我们用 C++ 编写了非常相似的代码类型 class 但我的版本运行不正常,尽管它逐行(几乎)相同。
我的代码旨在保存用户的口袋妖怪,他们可以随意添加和删除。我的显示功能有效,但我的添加和删除功能无效。所有文件都在打开,但它并没有像预期的那样覆盖文件。真的不知道该怎么做,我是一个初学者,我知道的不多。
这是我目前得到的:
string name[100];
string type[100];
int level[100];
string newPokemon;
string newType;
int newLevel;
ifstream fin;
ofstream fout;
int numberOfPokemon = 0;
//Input Pokemon Info
cout << "Name of Pokemon: ";
getline(cin, newPokemon);
cin.ignore(100, '\n');
cout << "Pokemon type: ";
getline(cin, newType);
cin.ignore(100, '\n');
cout << "Pokemon level: "; //weird gap between "Pokemon type" and "pokemon level". I have to press enter twice from "pokemon type" to get to "pokemon level"
cin >> newLevel;
cin.ignore(5, '\n');
fin.open("pokemon.txt");
//Put file in array
if (fin.is_open())
{
while (isalnum(fin.peek()) && numberOfPokemon < 100)
{
getline(fin, name[numberOfPokemon]);
getline(fin, type[numberOfPokemon]);
fin >> level[numberOfPokemon];
fin.ignore(100, '\n');
if (name[numberOfPokemon] != newPokemon)
numberOfPokemon++;
}
fin.close();
}
//Output file
fout.open("pokemon.txt");
if (fout.is_open())
{
for (int i = 0; i < numberOfPokemon; i++)
{
fout << name[i] << "\n";
fout << type[i] << "\n";
fout << level[i] << "\n";
}
//Tack on new piece
fout << newPokemon << "\n";
fout << newType << "\n";
fout << newLevel << "\n";
fout.close();
cout << "Add Successful\n";
}
else
{
cout << "Add Failure\n";
}
现在是我的删除功能:
string name[100];
string type[100];
int level[100];
int pokemonCount = 0;
string deletedPokemon = "";
bool found = false;
ifstream fin;
cout << "Which Pokemon would you like to delete?" << endl;
getline(cin, deletedPokemon);
cin.ignore(5, '\n');
fin.open("pokemon.txt");
if (fin.is_open())
{
while (isalnum(fin.peek()))
{
getline(fin, name[pokemonCount]);
getline(fin, type[pokemonCount]);
fin >> level[pokemonCount];
fin.clear();
fin.ignore(100, '\n');
if (deletedPokemon == name[pokemonCount])
{
pokemonCount--;
found = true;
}
pokemonCount++;
}
fin.close();
cout << "ya the file opened" << endl; //always appears
}
ofstream fout;
fout.open("pokemon.txt");
if (fout.is_open())
{
for (int i = 0; i < pokemonCount; i++)
{
fout << name[i] << "\n";
fout << type[i] << "\n";
fout << level[i] << endl;
}
fout.close();
cout << "pokemon removed\n";
cout << "the file opened."; //it is returning that the file opened in both occasions in this function but nothing is happening!
}
else
{
cout << "removal failure";
cout << "The file didn't open";
}
return found;
在此功能结束时(如果我选择删除一个),它会提供 "Would you like to add a Pokemon?" 但它不会让我输入答案,它只会结束程序。
ofstream::open
的默认行为是简单地打开文件进行读写。如果你想覆盖文件,你需要在调用 open
.
fout.open("pokemon.txt", ios_base::in|ios_base::out|ios_base::trunc);
确保您的文件未在属性下标记为只读。
此外,您的删除功能有一个错误:
bfound 应替换为 nDelete pokemon,当您写出文件时:
if (deletedPokemon == name[pokemonCount])
{
pokemonCount--;
found = true;
nDeleteIndex = i;
}
....
for (int i = 0; i < pokemonCount; i++)
{
if(i == nDeleteIndex)
continue;
fout << name[i] << "\n";
fout << type[i] << "\n";
fout << level[i] << endl;
}
现在它会重写你所有的口袋妖怪,而不会跳过你想删除的那个!
此外,如果用户有 155 个宠物小精灵作为完整索引,会发生什么情况。您要使用:
std::vector<string> names;
....
string szPokemon;
getline(fin, name[numberOfPokemon]);
names.push_back(szPokemon);
因此您不再有限制!
这是更简洁的代码,它更易于维护,每当你 add/remove 来自口袋妖怪的字段(闪亮?Male/Female?独特?)你将能够轻松地在CPokemonObject 而不是必须复制粘贴代码 100 次。
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
#define POKEMON_FILE "Pokemon.txt"
class CPokemon
{
public:
string szName;
string szType;
int nLevel;
CPokemon() : szName("Pika"), nLevel(10), szType("Lightning")
{};
void Read(ifstream &file)
{
file >> szName;
file >> szType;
file >> nLevel;
};
void Write(ofstream &file)
{
file << szName << endl;
file << szType << endl;
file << nLevel << endl;
};
void CreatePokemon()
{
//Input Pokemon Info
cout << "Name of Pokemon: ";
getline(cin, szName);
cout << "Pokemon type: ";
getline(cin, szType);
cout << "Pokemon level: "; //weird gap between "Pokemon type" and "pokemon level". I have to press enter twice from "pokemon type" to get to "pokemon level"
cin >> nLevel;
}
};
void WritePokemons(vector<CPokemon>& Pokemons)
{
ofstream fout;
fout.open(POKEMON_FILE);
//check the file open
if (!fout.is_open())
{
cout << "removal failure";
cout << "The file didn't open";
return;
}
//Write out all the pokemons
for (unsigned int i = 0; i < Pokemons.size(); i++)
Pokemons[i].Write(fout);
fout.close();
}
void ReadPokemons(vector<CPokemon>& Pokemons)
{
ifstream fin;
fin.open(POKEMON_FILE);
if (fin.is_open())
{
while (isalnum(fin.peek()))
{
CPokemon Pokemon;
Pokemon.Read(fin);
Pokemons.push_back(Pokemon);
}
fin.close();
cout << "ya the file opened" << endl; //always appears
}
}
bool DeletePokemon()
{
vector<CPokemon> Pokemons;
string szPokemonToDelete = "";
cout << "Which Pokemon would you like to delete?" << endl;
cin >> szPokemonToDelete;
//Read all pokemons
ReadPokemons(Pokemons);
ofstream fout;
fout.open("pokemon.txt");
//check the file open
if (!fout.is_open())
{
cout << "removal failure";
cout << "The file didn't open";
return false;
}
bool bFound = false;
for (unsigned int i = 0; i < Pokemons.size(); i++)
{
//Skip the pokemon to delete
if(Pokemons[i].szName == szPokemonToDelete)
{
bFound = true; //we found the pokemon to delete
continue;
}
Pokemons[i].Write(fout);
}
fout.close();
return bFound;
}
void AddPokemon()
{
vector<CPokemon> Pokemons;
//Read all pokemons from the file
ReadPokemons(Pokemons);
//Create the new porkemon
CPokemon Pokemon;
Pokemon.CreatePokemon();
//Add the pokemon to the list
Pokemons.push_back(Pokemon);
//Output file
WritePokemons(Pokemons);
}