Domanda

Ogni volta che faccio qualche cosa, e il mio while (1) viene chiamato nella mia funzione principale, il mio file viene cancellato. Mi sta facendo diventare pazzo. Ho provato di tutto. Io cerco di mettere la mia ofstream out ( "data.dat"); al di fuori del while (1) dichiarazione in modo che non si chiama ogni volta, ma poi nulla è scritto nel file come l'ofstream non è nemmeno lavorando!

Ho cercato di fare l'ofstream statica, in modo che non si chiama più e più volte, come:

static ofstream open("data.dat");

Questo non funziona.

E come ho detto, quando ho messo l'ofstream FUORI l'istruzione while, nulla è scritto nel file. Come:

ofstream out("data.dat");

    while (1)
    {


        string line = "";
        cout << "There are currently " << structList.size() << " items in memory.";
        cout << endl << endl;
        cout << "Commands: " << endl;
        cout << "1: Add a new record " << endl;
        cout << "2: Display a record " << endl;
        cout << "3: Edit a current record " << endl;
        cout << "4: Delete a record " << endl;
        cout << "5: Save current information " << endl;
        cout << "6: Exit the program " << endl;
        cout << endl;
        cout << "Enter a command 1-6: ";

        getline(cin , line);

        int rValue = atoi(line.c_str());

        system("cls");

        switch (rValue)
        {
            case 1:
                structList = addItem(structList);
                break;
            case 2:
                displayRecord(structList);
                break;
            case 3:
                structList = editRecord(structList);
                break;
            case 4:
                deleteRecord(structList);
                break;
            case 5:
                if (!structList.size()) { cout << "There are no items to save! Enter one first!" << endl << endl; system("pause"); system("cls"); break; }
                writeVector(out , structList);
                break;
            case 6:
                return 0;
            default:
                cout << "Command invalid. You can only enter a command number 1 - 6. Try again. " << endl;
        }

        out.close();
    }

E qualcuno può dirmi il motivo per cui il mio assegno per impedire la lettura di un file vuoto non funziona?

Check:

bool checkFileEmpty()
{
    ifstream in("data.dat");

    if (in.peek() == in.eofbit)
    {
        return true;
    }

    return false;
}

Sono così malato e stanco del mio programma di crash all'avvio più e più volte perché il mio vettore è sempre impostata su una dimensione di 200 milioni. Ho provato un sacco di roba per questo ... nessuno di esso funziona ... piacere a Dio qualcuno mi aiuti con entrambi questi! Sono in piedi per 18 ore di lavoro su questo (per tutta la notte yes) e ho quasi finito. Ti prego ....

My Code:

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace System;
using namespace std;
#pragma hdrstop

bool isValidChoice(int size, int choice);

bool checkFileEmpty();

template<typename T>
void writeVector(ofstream &out, const vector<T> &vec);

template<typename T>
vector<T> readVector(ifstream &in);

template<typename T>
vector<T> addItem(vector<T> &vec);

template<typename T>
void printItemDescriptions(vector<T> &vec);

template<typename T>
int displayRecord(vector<T> &vec);

template<typename T>
vector<T> editRecord(vector<T> &vec);

template<typename T>
vector<T> deleteRecord(vector<T> &vec);


struct InventoryItem {
    string Description;
    int Quantity;
    int wholesaleCost;
    int retailCost;
    string dateAdded;
} ;


int main(void)
{
    cout << "Welcome to the Inventory Manager extreme! [Version 1.0]" << endl;
    ifstream in("data.dat");
    if (in.is_open()) { cout << "File \'data.dat\' has been opened successfully." << endl; } else { cout << "Error opening data.dat" << endl;}
    cout << "Loading data..." << endl;
    vector<InventoryItem> structList = readVector<InventoryItem>( in );
    cout <<"Load complete." << endl << endl;
    in.close();

    while (1)
    {


        string line = "";
        cout << "There are currently " << structList.size() << " items in memory.";
        cout << endl << endl;
        cout << "Commands: " << endl;
        cout << "1: Add a new record " << endl;
        cout << "2: Display a record " << endl;
        cout << "3: Edit a current record " << endl;
        cout << "4: Delete a record " << endl;
        cout << "5: Save current information " << endl;
        cout << "6: Exit the program " << endl;
        cout << endl;
        cout << "Enter a command 1-6: ";

        getline(cin , line);

        int rValue = atoi(line.c_str());

        system("cls");

        ofstream out("data.dat");

        switch (rValue)
        {
            case 1:
                structList = addItem(structList);
                break;
            case 2:
                displayRecord(structList);
                break;
            case 3:
                structList = editRecord(structList);
                break;
            case 4:
                deleteRecord(structList);
                break;
            case 5:
                if (!structList.size()) { cout << "There are no items to save! Enter one first!" << endl << endl; system("pause"); system("cls"); break; }
                writeVector(out , structList);
                break;
            case 6:
                return 0;
            default:
                cout << "Command invalid. You can only enter a command number 1 - 6. Try again. " << endl;
        }

        out.close();
    }

    system("pause");

    return 0;
}

template<typename T>
void writeVector(ofstream &out, const vector<T> &vec)
{
    out << vec.size();

    for(vector<T>::const_iterator i = vec.begin(); i != vec.end(); i++)
    {
        out << *i;
    }
    cout << "Save completed!" << endl << endl;
}

ostream &operator<<(ostream &out, const InventoryItem &i)
{
    out << i.Description << ' ';
    out << i.Quantity << ' ';
    out << i.wholesaleCost  << ' ' << i.retailCost  << ' ';
    out << i.dateAdded  << ' ';
    return out;
}


istream &operator>>(istream &in, InventoryItem &i)
{
    in >> i.Description;
    in >> i.Quantity;
    in >> i.wholesaleCost >> i.retailCost;
    in >> i.dateAdded;
    return in;
}



template<typename T>
vector<T> readVector(ifstream &in)
{

    size_t size;
    if (checkFileEmpty())
    {
        size = 0;
    } else {
        in >> size;
    }

    vector<T> vec;
    vec.reserve(size);

    for(unsigned int i = 0; i < size; i++)
    {
        T tmp;
        in >> tmp;
        vec.push_back(tmp);
    }

    return vec;
}

template<typename T>
vector<T> addItem(vector<T> &vec)
{
    system("cls");

    string word;
    unsigned int number;

    InventoryItem newItem;

    cout << "-Add a new item-" << endl << endl;
    cout << "Enter the description for the item: ";
    getline (cin , word);
    newItem.Description = word;

    cout << endl;
    cout << "Enter the quantity on hand for the item: ";
    getline (cin , word);
    number = atoi(word.c_str());
    newItem.Quantity = number;

    cout << endl;
    cout << "Enter the Retail Cost for the item: ";
    getline (cin , word);
    number = atoi(word.c_str());
    newItem.retailCost = number;

    cout << endl;
    cout << "Enter the Wholesale Cost for the item: ";
    getline (cin , word);
    number = atoi(word.c_str());
    newItem.wholesaleCost = number;

    cout << endl;
    cout << "Enter current date: ";
    getline (cin , word);
    newItem.dateAdded = word;

    vec.push_back(newItem);

    return vec;
}

template<typename T>
void printItemDescriptions(vector<T> &vec)
{
    int size = vec.size();

    if (size)
    {
        cout << "---------------------------------" << endl;
        cout << "|      ~ Item Descriptions ~    |" << endl;
        cout << "---------------------------------" << endl;
        cout << "*********************************" << endl;
        for (int i = 0 ; i < size ; i++)
        {
            cout << "(" << i+1 << ")" << ": " << vec[i].Description << endl;
        }
        cout << "*********************************" << endl << endl;
    }
}

template<typename T>
int displayRecord(vector<T> &vec)
{
    string word = "";
    string quit = "quit";
    int choice = 1;
    int size = vec.size();

    if (size)
    {
        printItemDescriptions(vec);
        cout << endl;

        while (1)
        {
            cout << "Type \"exit\" to return to the Main Menu." << endl << endl;
            cout << "Enter \"list\" to re-display the items." << endl << endl;
            cout << endl;
            cout << "Pick the number of the item you would like to display: ";
            getline (cin , word);

            if (convertToLower(word) == "exit") { system("cls"); return 0; }
            if (convertToLower(word) == "list") { system("cls"); displayRecord(vec); }

            choice = atoi(word.c_str());

            choice -= 1;

            if (isValidChoice(size, choice))
            {
                system("cls");
                cout << endl << "[Item (" << choice << ") details] " << endl << endl;
                cout << "******************" << endl;
                cout << "*  Description   * " << vec[choice].Description << endl;
                cout << "******************" << endl << endl;
                cout << "******************" << endl;
                cout << "*Quantity On Hand* " << vec[choice].Quantity << endl;
                cout << "******************" << endl << endl;
                cout << "******************" << endl;
                cout << "* Wholesale Cost * " << vec[choice].wholesaleCost << endl;
                cout << "****************** " << endl << endl;
                cout << "******************" << endl;
                cout << "*  Retail Cost   * " << vec[choice].retailCost << endl;
                cout << "****************** " << endl << endl;
                cout << "******************" << endl;
                cout << "*  Data Added    * " << vec[choice].dateAdded << endl;
                cout << "****************** " << endl << endl;
            } else { system("cls"); cout << "That item doesn't exist!" << endl; cout << "Pick another item or enter \"list\" to see available items." << endl << endl; }
        }
    } else { cout << "There are currently no items to display." << endl << endl; system("pause"); system("cls"); return 0; }

    return 1;
}

bool isValidChoice(int size, int choice)
{
    for (int i = 0 ; i <= size ; i++)
    {
        if (choice == i) { return true; }
    }
    return false;
}

string convertToLower(string word)
{
    for (unsigned int i = 0 ; i < word.size() ; i++)
    {
        word[i] = tolower(word[i]);
    }

    return word;
}

bool checkFileEmpty()
{
    ifstream in("data.dat");

    if (in.peek() == in.eofbit)
    {
        return true;
    }

    return false;
}

template<typename T>
vector<T> editRecord(vector<T> &vec)
{
    string word;
    int choice;
    printItemDescriptions(vec);

    cout << "Choose item to edit: ";
    getline ( cin, word );
    choice = atoi(word.c_str());


    system("cls");

    unsigned int number;

    InventoryItem newItem;

    cout << "-Edit an item-" << endl << endl;
    cout << "Enter the description for the item: ";
    getline (cin , word);
    vec[choice-1].Description = word;

    cout << endl;
    cout << "Enter the quantity on hand for the item: ";
    getline (cin , word);
    number = atoi(word.c_str());
    vec[choice-1].Quantity = number;

    cout << endl;
    cout << "Enter the Retail Cost for the item: ";
    getline (cin , word);
    number = atoi(word.c_str());
    vec[choice-1].retailCost = number;

    cout << endl;
    cout << "Enter the Wholesale Cost for the item: ";
    getline (cin , word);
    number = atoi(word.c_str());
    vec[choice-1].wholesaleCost = number;

    cout << endl;
    cout << "Enter current date: ";
    getline (cin , word);
    vec[choice-1].dateAdded = word;

    system("cls");

    cout << "Item edited successfully! " << endl;

    return vec;
}

template<typename T>
vector<T> deleteRecord(vector<T> &vec)
{
    if (!vec.size()) { cout << "There are no items to delete!" << endl << endl; return vec; }
    printItemDescriptions(vec);

    string word;
    int choice;

    cout << "Choose item to delete: ";

    getline( cin, word);

    choice = atoi(word.c_str());

    vec.erase (vec.begin()+choice-1);
    return vec;
}
È stato utile?

Soluzione

Faresti meglio a spostare l'apertura e la chiusura ofstream all'interno caso 5.

Qui si crea un nuovo file per ogni mentre l'iterazione.

case 5:
        {
            ofstream out("data.dat");
            writeVector(out , structList);
            out.close();
        }
        break;

Altri suggerimenti

ofstream out("data.dat");

Apre il file per la scrittura. Per impostazione predefinita, inizierà proprio all'inizio spazzando via tutto ciò che c'era in precedenza. In primo luogo, utilizzare un file di output diverso da quello del file che si sta leggendo da.

Prova ad aggiungere la chiusura al caso 6 dichiarazioni:

case 6:
        out.close();
        return 0;

Sono abbastanza sicuro che il vicino non è sempre chiamato come il ritorno sarà uscita principale prima di arrivare a questa affermazione. Con aperse il file che si sono lasciati con un buffer unflushed e ho il sospetto che lascerà i dati non scritti.

Si dovrebbe spostare il aperta a prima del ciclo while e rimuovere anche l'out.close () dal ciclo while come sta andando a chiudere il file dopo la prima selezione di menu.

Per verificare se un file è vuoto o non può essere aperto

bool IsEmpty( const std::string & filename ) {

   std::ifstream ifs( filename.c_str() );

   if ( ifs.is_open() ) {
      std::string line;
      return ! std::getline( ifs, line );
   }
   else {
      return true;
   }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top