Почему не работает мой оффстрим, когда я помещаю это вне моего выражения while? - PullRequest
0 голосов
/ 02 апреля 2009

Каждый раз, когда я что-то делаю, и мой while (1) вызывается в моей основной функции, мой файл очищается. Это сводит меня с ума. Я пробовал ВСЕ. Я пытаюсь выставить свой оффстрим ("data.dat"); за пределами оператора while (1), поэтому он не вызывается каждый раз, но тогда в файл ничего не записывается, как thestream даже не работает!

Я пытался сделать статический поток ofstream таким образом, чтобы он не вызывался снова и снова, например:

static ofstream open("data.dat");

Это не работает.

И, как я уже сказал, когда я помещаю офлайн-поток вне оператора while, в файл ничего не записывается. Как:

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

А может кто-нибудь сказать мне, почему моя проверка для предотвращения чтения пустого файла не работает?

Мой чек:

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

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

    return false;
}

Мне так надоело, что моя программа зависала при запуске снова и снова, потому что мой вектор был установлен в размере 200 миллионов. Я попробовал кучу вещей для этого ... ничего из этого не работает ... Пожалуйста, БОГ, кто-нибудь, помогите мне с обоими из них! Я работал в течение 18 часов, работая над этим (всю ночь, да), и я почти все сделал. Я умоляю тебя ....

Мой код:

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

Ответы [ 4 ]

2 голосов
/ 02 апреля 2009

Вам лучше переместить открытие и закрытие ofstream внутри корпуса 5.

Здесь вы создаете новый файл на каждой итерации.

case 5:
        {
            ofstream out("data.dat");
            writeVector(out , structList);
            out.close();
        }
        break;
0 голосов
/ 02 апреля 2009

Попробуйте добавить операторы close к case 6:

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

Я почти уверен, что закрытие не вызывается, так как возвращение выйдет из main, прежде чем перейти к этому утверждению. Если файл не закрыт, у вас останется незаполненный буфер, и я подозреваю, что данные останутся не записанными.

Вы должны переместить open до цикла while, а также удалить out.close () из цикла while, поскольку он собирается закрыть файл после первого выбора меню.

0 голосов
/ 02 апреля 2009

Чтобы проверить, является ли файл пустым или не может быть открыт

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;
   }
}
0 голосов
/ 02 апреля 2009
ofstream out("data.dat");

Открывает файл для записи. По умолчанию это начнется в самом начале, уничтожая все, что было там ранее. Сначала используйте выходной файл, отличный от файла, из которого вы читаете.

...