0

好吧,我已经为这个问题苦苦挣扎了好几个小时。但由于某些原因,我找不到该死的错误。我真的希望你能最终帮助我。

接下来,我编写了一个程序,用户必须在其中插入一些关于他的事实。名字 = vname,姓氏 = nname,他的帐户 = echte_kontonummer,他的 Pin 和程序会将这个和他的信用写入 a 文件。不要误解我,这只是为了学习目的,我永远不会用这个进行网络钓鱼;D。

但是,该工具将此数据写入文件。到目前为止还不错,但现在它应该逐行读取文件。并将文本形成我需要进一步操作的变量。

但由于某些原因,它只是读取愚蠢的随机数字和字符。

最后是加载文件的方法:

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

并在这里完成这门课

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

顺便说一句,语言是德语,希望这没关系。

哦,是的,这里解释了循环是如何工作的

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

1 回答 1

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

     else
         getline(user1, inhalt_anrede);

 }

上面的代码包含了你对文件的第一次读取,我们来分析一下它的作用。anrede 从 1 开始,让我们假设文件充满了数据,所以我们还没有接近结尾,所以我们进入循环。

您检查 anrede==1,它确实如此,因此您将 inhalt_anrede(为空)的值复制到 Anrede。所以现在 Anrede 是一个空且正确以 null 结尾的字符串。然后你增加 anrede。我们还没有从文件中读取任何内容,所以我们当然还没有达到 eof,所以我们进入了循环。

再次,我们检查 anrede==1。它没有,所以我们执行 else 部分,它从文件中获取一行并将其存储到 inhalt_anrede 中。再次递增 anrede,假设我们还没有达到 eof,所以我们再次进入循环。

连续重复上一段,逐行读取文件并丢弃结果,直到达到eof,然后循环结束。其余的 for 循环都要求我们没有达到 eof。但是我们已经到了 eof,所以这些循环被跳过了。

由于您尚未定义默认构造函数,所有这些成员都未初始化,这就是您看到随机数和字符的原因。

修复

我要做的第一件事就是将你类中的那些 char 数组更改为 std::string,因为它让我的生活更简单。我还将这些 ifstream 从类中删除,它们没有理由存在,我们将在需要时创建它们。现在对于函数,我不确切知道您的文件是如何布局的,这是根据您提供的内容进行的猜测,但是是这样的:

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

该函数还假定文件是正确的,因此不进行错误检查。如果需要,可以检查每个 getline 的返回值,例如:

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

如果您想检查数字转换是否有效,您将需要使用新的 C++11 函数stoi,stoll,etc... 之类的东西,它们会在错误时引发异常。如果这些不可用,还有字符串流,您可以像这样检查:

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

或者你可以使用boost lexical_cast,它在内部使用字符串流,并且会在出错时抛出异常。

于 2011-09-09T17:25:55.833 回答