我的代码没有覆盖文本文件,即使它应该覆盖?

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);
}