2009-04-02 6 views
1

Comme la plupart d'entre vous suivent peut-être ma ligne de questions, je suis en train de créer un programme capable de sérialiser plusieurs structs dans un fichier .dat, de les relire en chargeant sa sérialisation, d'en éditer le contenu, puis réécrivez-les dans le fichier et ainsi de suite. C'est un programme d'inventaire que j'essaie de faire et je ne peux pas le faire fonctionner pour la vie de moi.Pourquoi la taille de mon vecteur est-elle si importante lorsque je charge la sérialisation à partir d'un fichier?

Le fichier en cours de chargement est vide. Mon programme prend environ 10 secondes pour charger et maintenant je sais pourquoi. C'est parce que la taille de mon vecteur est de 250 000. Oh attends ... cette fois je l'ai couru la taille de mon vecteur était de 5 172 285. C'est un très gros vecteur plein de structures. Il n'y a pas d'erreurs d'exécution ou de compilation, mais je suis sûr que je fais quelque chose de mal. Le fichier que je charge est complètement vide aussi.

code:

// Project 5.cpp : main project file. 

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

using namespace System; 
using namespace std; 
#pragma hdrstop 

int checkCommand (string line); 

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

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

struct InventoryItem { 
    string Item; 
    string Description; 
    int Quantity; 
    int wholesaleCost; 
    int retailCost; 
    int 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; return 0;} 
    cout << "Loading data..." << endl; 
    vector<InventoryItem> structList = readVector<InventoryItem>(in); 
    cout <<"Load complete." << endl; 

    while (1) 
    { 

     string line = ""; 
     cout << "There are currently " << structList.size() << " items in memory."; 
     cout << 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: Exit the program " << endl; 
     cout << endl; 
     cout << "Enter a command 1-4: "; 

     getline(cin , line); 


     int rValue = checkCommand(line); 
     if (rValue == 1) 
     { 
      cout << "You've entered a invalid command! Try Again." << endl; 
     } else if (rValue == 2){ 
      cout << "Error calling command!" << endl; 
     } else if (!rValue) { 
      break; 
     } 
    } 


    system("pause"); 

    return 0; 
} 

int checkCommand (string line) 
{ 
    int intReturn = atoi(line.c_str()); 
    int status = 3; 

    switch (intReturn) 
    { 
     case 1: 
      break; 
     case 2: 
      break; 
     case 3: 
      break; 
     case 4: 
      status = 0; 
      break; 
     default: 
      status = 1; 
      break; 
    } 
    return status; 
} 

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

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

istream &operator>>(istream &in, InventoryItem &i) 
{ 
    in >> i.Item >> 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; 
    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; 
} 

Quelqu'un peut-il simplement me montrer comment transformer ce pour un programme qui peut réellement écrire des vecteurs sérialisés pleine de struct dans un fichier, puis les relire je peux les éditer et les stocker pour les charger plus tard? Oh mon dieu quelle promenade ça a été!

MERCI pour toute aide que vous pouvez fournir!

+0

mieux essayer de faire vos devoirs par vous-même – jab

+0

Il est correct de poser des questions sur des sujets de devoirs, l'étiquette est de ne pas résoudre le problème et que pour donner des conseils et des suggestions quant au problème. Il peut être décourageant de ne pas avoir d'aide du tout lorsque vous essayez d'apprendre –

Répondre

5

Vous dites que le fichier est réellement vide. La première ligne de readVector est la suivante:

in >> size; 

Qu'est-ce qui va réellement se terminer? Comme il est vide, il en résulte une erreur que vous ne détectez pas. La variable size restera non initialisée - d'où vous voyez des valeurs bizarres, car il prend toute la valeur qui est passée en mémoire à ce moment-là. Vous pouvez vérifier l'état du cours d'eau en utilisant le chèque:

if (in) 

traitement dans le contexte booléen indique si une erreur est survenue - cela couvrira aussi des choses comme étant incapable de lire dans une variable entier valide. Je suggère que vous deviez comprendre comment exécuter votre programme dans un débogueur, vous serez en mesure de parcourir votre code et de voir quelles sont les valeurs des variables à un moment donné.

+0

J'ai essayé \t si (dans) \t { dans >> taille; \t} else { \t \t size = 0; \t} Mais je reçois toujours le même problème. Était-ce la solution que vous avez suggérée? – OneShot

+0

Pas exactement. L'état d'erreur est défini après que vous essayez de lire dans le flux, pas avant –

+0

Eh bien que voulez-vous dire par là? – OneShot

3

Donc, si votre fichier est vide et votre pratique:

size_t size; 
in >> size; 

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

Que pensez-vous qui va se passer? La taille ne peut pas être lue et utilise une valeur aléatoire

+0

Comment puis-je empêcher cela de se produire? – OneShot

+0

Voir 1800 INFORMATION post et commentaires – RvdK

3

Si votre fichier d'entrée est vide, le vector doit être vide. Vous ne devriez pas dépasser la ligne:

if (in.is_open()) 

- votre programme (quand je le lance sur ma machine) se ferme.

Pouvez-vous expliquer pourquoi vous avez ce qui suit?

#include <String> 

using namespace System; 

#pragma hdrstop 

Le plus facile à mettre en œuvre est à lire dans le contenu du fichier en une seule fois, conserver les éléments en mémoire, les éditer en mémoire et d'écrire à déposer une fois par avec l'édition. Ce n'est bien sûr pas une très bonne technique de l'empreinte de la mémoire ou du point de vue de la performance. Mais alors, le problème que vous essayez de résoudre n'est pas trivial.Lisez FAQ 36 pour mieux comprendre votre tâche.

+0

Merci pour le lien aide & FAQ, assurez-vous de le lire. – OneShot

+0

Ohhh merde. C'est à cause de l'if (file.is_open) au début du fichier désolé – OneShot

0

Vous utilisez des fichiers vierges, mais lorsque vous chargez le fichier, vous recherchez une taille. Lorsque le fichier n'a pas de taille dans le fichier, vous risquez d'avoir des déchets dans votre variable de taille. Essayez donc de mettre un zéro dans la première ligne du fichier 'data.dat'.

Modifier: La suggestion ci-dessus était juste une solution temporaire. Vous pouvez essayer ceci:

in >> size; 
//input operation failed 
if(in.fail()) 
    //return, or whatever you need to do 
+0

Je ne pense pas que cela puisse être tout à fait correct, n'est-il pas préférable d'écrire le code de telle manière qu'il puisse gérer un fichier vide ? –

+0

Je suis d'accord. Je suggérais plutôt que c'était une solution temporaire ... J'aurais dû le mentionner. Oops! – Naxos

+0

Comment puis-je écrire du code qui empêche cela? – OneShot

Questions connexes