Чтение из данных не работает, но почему? - PullRequest
0 голосов
/ 09 сентября 2011

ну, я боролся с этой проблемой часами.но по некоторым причинам я не могу найти эту чертову ошибку.Я действительно надеюсь, что вы наконец-то сможете мне помочь.

После этого я написал программу, в которую пользователь должен вставить некоторые факты о нем.имя = имя, фамилия = имя, его учетная запись = echte_kontonummer, его пин-код и программа запишут это и его кредит в файл.не поймите меня неправильно, это только для целей обучения, я никогда не буду заниматься фишингом; 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
     }
 }

1 Ответ

2 голосов
/ 09 сентября 2011
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 - пустая и правильно завершенная нулем строка. Тогда ты увеличиваешь anrede. Мы еще ничего не прочитали из файла, поэтому мы, конечно, еще не достигли eof, поэтому мы входим в цикл.

Опять же, мы проверяем anrede == 1. Это не так, поэтому мы выполняем часть else, которая получает строку из файла и сохраняет ее в inhalt_anrede. Прибавьте еще раз, давайте предположим, что мы еще не достигли eof, поэтому мы снова входим в цикл.

Повторяйте предыдущий абзац непрерывно, читая файл построчно и отбрасывая результат до тех пор, пока мы не достигнем eof, затем цикл заканчивается. Все остальные циклы for требуют, чтобы мы не достигли eof. Но мы достигли eof, поэтому эти петли пропущены.

Поскольку вы не определили конструктор по умолчанию, все эти члены остаются неинициализированными, поэтому вы видите случайные числа и символы.

Исправление

Первое, что я делаю, это заменяю эти массивы символов в вашем классе на 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 и т. Д. ошибка. Если они недоступны, есть также строковые потоки, которые вы можете проверить следующим образом:

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

Или вы можете использовать boost lexical_cast , который использует строковые потоки внутри и генерирует исключения при ошибке.

...