2017-05-23 3 views
-1

Je reçois une erreur de segmentation et d'après ce que j'ai lu, c'est parce que j'essaie d'accéder à une partie de la mémoire à laquelle je n'ai pas droit.Mauvaise compréhension de la faute de segmentation

Je suis presque certain que mon problème se pose dans la boucle while de ma fonction ShowAccounts. Après plusieurs tentatives pour comprendre comment fonctionne cet appel à lire, je ne pense pas que je le comprenne correctement.

J'ai déjà créé 3 comptes de type BankAccount et ils sont stockés dans le fichier binaire AccountDetails.dat, cependant, je ne peux pas y accéder. Si vous ne parvenez pas à comprendre pourquoi je reçois cette erreur de segmentation, vous pourriez peut-être expliquer comment la fonction de lecture fonctionne et ce qu'elle essaie de faire, puis je peux en faire plus. évaluer? Toutes les réponses sont les bienvenues.

#include <iostream> 
#include <fstream> 
using namespace std; 

class BankAccount 
{ 
public: 
    void CreateAccount(); 
    void ShowAccount(); 
private: 
    int accountNumber; 
    string firstName; 
    string lastName; 
    char accountType; 
    double balance; 
}; 

void MakeAccount(); 
void ShowAccounts(); 

int main() 
{ 
    ShowAccounts(); 

    return 0; 
} 

void BankAccount::CreateAccount() 
{ 
    cout << "Enter the account number.\n"; 
    cin >> accountNumber; 
    cout << "Enter the first and last name of the account holder.\n"; 
    cin >> firstName >> lastName; 
    cout << "What kind of account is it? S for savings or C for checking.\n"; 
    cin >> accountType; 
    cout << "How much are you depositing into the account?\n"; 
    cin >> balance; 
    cout << "CREATED\n"; 
} 

void BankAccount::ShowAccount() 
{ 
    cout << "Account Number: " << accountNumber << endl; 
    cout << "Name: " << firstName << " " << lastName << endl; 
    cout << "Account Type: " << accountType << endl; 
    cout << "Current Balance: $" << balance << endl; 
} 

void MakeAccount() 
{ 
    BankAccount account; 
    ofstream output; 
    output.open("AccountDetails.dat", ios::binary|ios::app); 
    if (!output) 
     cerr << "Failed to open file.\n"; 
    account.CreateAccount(); 
    output.write((char *) &account, sizeof(BankAccount)); 
    output.close(); 
} 

void ShowAccounts() 
{ 
    BankAccount account; 
    ifstream input; 
    input.open("AccountDetails.dat", ios::binary); 
    if (!input) 
     cerr << "Failed to open file.\n"; 
    while (input.read((char *) &account, sizeof(BankAccount))) 
    { 
     account.ShowAccount(); 
    } 
    input.close(); 
} 
+3

Vous devez lire sur [Sérialisation] (https://en.wikipedia.org/wiki/Serialization) - La bonne façon de lire/écrire des données dans/depuis un fichier. Vous ne pouvez pas simplement écrire 'std :: string' dans un fichier. –

+3

Copie possible de [Sérialiser une classe qui contient une chaîne std ::] (https://stackoverflow.com/questions/7046244/serializing-a-class-which-contains-a-stdstring) – LogicStuff

+3

Il n'est pas possible de correctement 'read' ou' write' un objet qui contient des membres std :: string (ou std :: vector ou std :: list ou n'importe quel type de pointeur ou de fonctions virtuelles). Vous devez trouver un moyen de stocker ces objets qui n'impliquent pas 'read' (' << >> 'ok). –

Répondre

0

Lorsque vous essayez de lire des octets d'un flux d'entrée directement sur une structure contenant des pointeurs ou des chaînes, vous définirez les pointeurs qu'ils contiennent à ordures. (Les tableaux de caractères fonctionneront.) Tenter d'utiliser les pointeurs et les chaînes entraînera alors un comportement indéfini, ce qui peut entraîner une erreur de segmentation. Ou autre chose.

Pour vérifier cela, chargez le programme dans un débogueur, définissez un point d'arrêt sur cette ligne et exécutez. Lorsque vous y arrivez, inspectez la structure et ses membres pour voir si les données qu'ils contiennent sont valides.

Essayez d'adapter votre fonction BankAccount::CreateAccount() pour qu'elle soit non interactive.