2009-04-02 6 views
1

私は構造体を含むベクトルを.datファイルにシリアライズするとどうしたらいいですか?

説明に入力した場合:アップル

数量:10

卸売コスト:30

小売価格:追加されました20

日:12月

これらは、私の.datファイルの内容:

1Apple103020December

しかし、私は私のプログラムをロードするには、それは正しくあり私のリスト内の商品であることになるで構造体の背中をロードしません。それは、私が真剣に間違って何かをしているかのように見えるかと思いますか?

コード:あなたの読み取り機能で

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

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

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: 
       addItem(structList); 
       break; 
      case 2: 
       displayRecord(structList); 
       break; 
      case 3: 
       break; 
      case 4: 
       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 (in.fail()) 
    { 
    in >> size; 
    } else { 
     size = 0; 
    } 

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

      if (isValidChoice(size, choice)) 
      { 
       system("cls"); 
       cout << endl << "[Item (" << choice << ") details] " << endl << endl; 
       cout << "******************" << endl; 
       cout << "* Description * " << vec[choice-1].Description << endl; 
       cout << "******************" << endl << endl; 
       cout << "******************" << endl; 
       cout << "*Quantity On Hand* " << vec[choice-1].Quantity << endl; 
       cout << "******************" << endl << endl; 
       cout << "******************" << endl; 
       cout << "* Wholesale Cost * " << vec[choice-1].wholesaleCost << endl; 
       cout << "****************** " << endl << endl; 
       cout << "******************" << endl; 
       cout << "* Retail Cost * " << vec[choice-1].retailCost << endl; 
       cout << "****************** " << endl << endl; 
       cout << "******************" << endl; 
       cout << "* Data Added * " << vec[choice-1].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 == size) { return true; } 
    } 
    return false; 
} 

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

    return word; 
} 

答えて

3

if (in.fail()) 

は次のようになります。

if (! in.fail()) 

またはそれ以上:

int n; 

if (! (in >> n)) { 
    n = 0; 
} 
+0

私はこれを一度行いました。私のVectorは2千万を超えるサイズに設定されていたため、ベクターには大きすぎるエラーが発生していました。ファイルが空白の場合、ベクトルサイズを設定できないようにするにはどうすればよいですか? – OneShot

+0

ええ、私はそれをやった、サイズは数百万だったので私は致命的なエラーを持っています。失敗は役に立たないと思う? – OneShot

+0

Nを初期化しないとどのように機能しますか? – OneShot

1

いくつかのセパレータを使用してください。 ""(スペース)

+0

ええ、私はそれをやり遂げる方法についての手がかりがありません。私は時間のためにこれをしてきました.... – OneShot

+0

これを行う方法の例を教えてください。 – OneShot

+0

@cpitis already provided example =)) – bayda

1

DATファイルを保存するときに、文字列の間に空白(スペース/タブ)を追加する必要があります。

文字列を読み取るために>>演算子を使用すると、最初の空白文字(スペース/タブ/ EOL)が見つかるまで文字列を読み取ります。あなたのコードから

記述をロードするためにオペレータを>>使用した場合であってもそう、例えば、記述が不完全(最初のスペースまでロードされますを更新しました

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

保存された説明テキスト)。

+0

これで、負荷の問題が修正されますか? lol – OneShot

+0

あなたの説明に空白が含まれていれば...まだ読み込みに問題があります...説明の読み込みは最初のものに限られます。 シリアライズ/デシリアライズの場合、私の意見では、さらに進化したものが必要です。たとえばBoost.Serializationを参照してください。 –

1

この場合も、シリアライゼーションはあまり単純ではありません。あなたが図書館の学習に時間を費やすことができれば。

私は前にあなたが作った質問に与えたanswerを再投稿するつもりはありませんが、本当にそれを見てください。あなたが直面しているいくつかの問題点を説明し、解決策を提供します。

+0

申し訳ありません。私はあなたのリンクを読んだ。私はプロジェクトを完成させようとしているので、理解できる作業参照のためにそれを見ることができます。私はこれに15時間プラスしています。なぜ、ここで何度も質問をしなければならない理由を理解してください。あなたが私に与えたすべての助けを本当にありがとう。 – OneShot

+0

これは問題ありません。私はそれがあなたを助けることを願っ:) –

関連する問題