开发者

Reading from Data doesn't work, but why?

well, i've struggeling with this problem for hours. but for some reasons i can't find the damn mitstake. I really hope that u can finally help me.

following, i've written a program where the user has to insert some facts about him. first name = vname, last name=nname, his account = echte_kontonummer, his Pin and the programm will write this and his credit into the a file. don't misunderstand me, it's for learning purposes only i will never went phishing with this ;D.

However, the tool write this datas into the file. as far so good but now it should read the file line by line. and form the text into variables i need for further operations.

but for some reasons, it just read stupid randon numbers and characters.

finally here is the methode which loads a file:

void Kunde::laden(){
    string inhalt_anrede, inhalt_vname, inhalt_nname, inhalt_knumme开发者_开发技巧r, inhalt_pin, inhalt_guthaben;
    int anrede, vorname, nachname, knummer, pin, guthaben;

    system("cls");
    cout << "wie ist ihr nachname?" << endl;
    cin  >> nname;

    user1.open(nname, ios::in);

    if(!user1.is_open()){
        cout << "Datei nicht gefunden" << endl;
    }

    if(user1.is_open()){

     for ( anrede=1;!user1.eof();anrede++){
         if (anrede==1){
             strcpy(Anrede,inhalt_anrede.c_str());
         }

         else
             getline(user1, inhalt_anrede);

     }
     for ( vorname=1;!user1.eof();vorname++){
         if (vorname==2){
             strcpy(vname,inhalt_vname.c_str());
         }

         else
             getline(user1, inhalt_vname);

     }

     for ( nachname=1;!user1.eof();nachname++){
         if (nachname==3){
             strcpy(nname,inhalt_nname.c_str());
         }

         else
             getline(user1, inhalt_nname);

     }
     for ( knummer=1;!user1.eof();knummer++){
         if (knummer==4){
             echte_kontonummer=atol(inhalt_knummer.c_str());
         }

         else
             getline(user1, inhalt_knummer);

     }
     for ( pin=1;!user1.eof();pin++){
         if (pin==5){
             echte_pin=atoi(inhalt_pin.c_str());
         }

         else
             getline(user1, inhalt_pin);

     }
     for ( guthaben=1;!user1.eof();guthaben++){
         if (guthaben==6){
             Guthaben=atoi(inhalt_guthaben.c_str());
         }

         else
             getline(user1, inhalt_guthaben);

     }
     cout << "Daten erfolgreich geladen." << endl;
     cout << vname << " " << nname << " " << echte_kontonummer << " " << echte_pin << " " << Guthaben << endl;
   }
     user1.close();
}

and to complete this here is the class

class Kunde{
private:
    char Anrede[5];
    char vname[20];
    char nname[20];
    long long echte_kontonummer;
    int  echte_pin;
    int  Guthaben;
    fstream user;
    ifstream user1;
public:
    void einpflegen();
    void login();
    void einzahlen();
    void speichern();
    void laden();
    void zeige_guthaben();
};

btw the language is german, hope this doesn't matter.

oh yes and here is a explanation of how the loop works

 for ( int guthaben=1;!user1.eof();guthaben++){ //i think this is understandable
     if (guthaben==4){ //in this case the desired value is on line 4 (the account number.
         getline(user1, inhalt_guthaben);       
         echte_kontunummer=atol(inhalt_knummer.c_str()); //from string to int to the desired value Guthaben. here foe e.g i only get random numbers when the console should put out this value
     }
 }


for ( anrede=1;!user1.eof();anrede++){
     if (anrede==1){
         strcpy(Anrede,inhalt_anrede.c_str());
     }

     else
         getline(user1, inhalt_anrede);

 }

The above code contains your first read of the file, let's analyze what it does. anrede starts out at 1, let's assume the file is full of data, so we are not near the end, so we enter the loop.

You check if anrede==1, it does, so you copy the value of inhalt_anrede(which is empty) into Anrede. So now Anrede is an empty and properly null-terminated string. Then you increment anrede. We haven't read anything from the file yet, so we of course still haven't reached eof, so we enter the loop.

Again, we check if anrede==1. It doesn't, so we execute the else portion, which gets a line from the file and stores it into inhalt_anrede. Increment anrede again, let's assume we still haven't reached eof, so we enter the loop again.

Repeat the above paragraph continuously, reading the file line-by-line and discarding the result until we have reached eof, then the loop ends. The rest of the for loops all require that we haven't reached eof. But we have reached eof, so those loops are skipped.

Since you haven't defined a default constructor, all those members are left uninitialized, which is why you see random numbers and characters.

The Fix

The first thing I do is change those char arrays in your class to std::string, because it makes my life simpler. I also remove those ifstreams from the class, there is no reason for them to be there, we will create them when we need them. Now for the function, I don't know exactly how your file is laid out, this is a guess based on what you've provided, but something like this:

void Kunde::laden(){
    string temp;

    system("cls");
    cout << "wie ist ihr nachname?" << endl;
    cin  >> nname;

    ifstream user1(nname);   

    if(!user1.is_open()){
        cout << "Datei nicht gefunden" << endl;
        return;
    }

    getline(user1,Anrede);
    getline(user1,vname);
    getline(user1,nname);
    getline(user1,temp);
    echte_kontonummer = atol(temp.c_str());
    getline(user1,temp);
    echte_pin = atoi(temp.c_str());
    getline(user1, temp);
    Guthaben = atoi(temp.c_str());

    cout << "Daten erfolgreich geladen." << endl;
    cout << vname << " " << nname << " " << echte_kontonummer << " " << echte_pin << " " << Guthaben << endl;
}

The function also assumes that the file is correct and so does no error checking. If you want, you can check the return value of each getline, e.g.:

if (!getline(user1,Anrede)) {
    // handle error somehow
}

If you want to check that the numeric conversions are valid, you'll want to use something like the new C++11 functions, stoi,stoll,etc..., which throw exceptions on error. If those aren't available, there's also string streams, which you can check like this:

istringstream iss(temp);
if (!(iss >> echte_kontonummer)) {
    // handle error somehow
}

Or you can use boost lexical_cast, which uses string streams internally, and will throw exceptions on error.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜