简体   繁体   English

从数据中读取不起作用,但为什么?

[英]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. 但由于某些原因,我找不到该死的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. first name = vname,last name = nname,他的account = echte_kontonummer,他的Pin和programm会把这个和他的信用写入一个文件。 don't misunderstand me, it's for learning purposes only i will never went phishing with this ;D. 不要误解我,这只是为了学习目的,我永远不会用这种方式进行网络钓鱼; 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. 但由于某些原因,它只是阅读愚蠢的randon数字和字符。

finally here is the methode which loads a file: 最后这里是加载文件的方法:

void Kunde::laden(){
    string inhalt_anrede, inhalt_vname, inhalt_nname, inhalt_knummer, 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. anrede从1开始,让我们假设文件中充满了数据,所以我们还没有接近结束,所以我们进入循环。

You check if anrede==1, it does, so you copy the value of inhalt_anrede(which is empty) into Anrede. 你检查anrede == 1是否确实如此,所以你将inhalt_anrede(为空)的值复制到Anrede中。 So now Anrede is an empty and properly null-terminated string. 所以现在Anrede是一个空的,正确的以null结尾的字符串。 Then you increment anrede. 然后你增加anrede。 We haven't read anything from the file yet, so we of course still haven't reached eof, so we enter the loop. 我们还没有从文件中读取任何内容,所以我们当然还没有达到eof,所以我们进入循环。

Again, we check if anrede==1. 再次,我们检查anrede == 1。 It doesn't, so we execute the else portion, which gets a line from the file and stores it into inhalt_anrede. 它没有,所以我们执行else部分,它从文件中获取一行并将其存储到inhalt_anrede中。 Increment anrede again, let's assume we still haven't reached eof, so we enter the loop again. 再次增加anrede,让我们假设我们还没有达到eof,所以我们再次进入循环。

Repeat the above paragraph continuously, reading the file line-by-line and discarding the result until we have reached eof, then the loop ends. 连续重复上面的段落,逐行读取文件并丢弃结果直到我们达到eof,然后循环结束。 The rest of the for loops all require that we haven't reached eof. 其余的for循环都要求我们没有达到eof。 But we have reached eof, so those loops are skipped. 但是我们已经达到了eof,所以跳过了这些循环。

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. 我做的第一件事是将类中的char数组更改为std :: string,因为它使我的生活变得更简单。 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. 我也从班级中删除了那些ifstreams,没有理由让他们在那里,我们会在需要时创建它们。 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, eg: 如果需要,您可以检查每个getline的返回值,例如:

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. 如果你想检查数字转换是否有效,你会想要使用类似新的C ++ 11函数, stoi,stoll等... ,这会在出错时抛出异常。 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. 或者你可以使用boost lexical_cast ,它在内部使用字符串流,并会在出错时抛出异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM