Я не могу прочитать из файлов для подтверждения имени пользователя

#c #fstream

#c #fstream

Вопрос:

Я пытаюсь создать программу, в которой вы должны войти в систему с именем пользователя (чтобы упростить ее, я сначала использую имя пользователя, я добавлю пароль некоторое время спустя) Чтобы заставить это работать, я хочу записать имя пользователя в файл (который я зашифрую позже), и когда вы захотите войти в систему, он проверит через файл, действительно ли имя пользователя правильное. Но когда я ввожу ошибочное имя пользователя, он автоматически входит в систему и не запрашивает создание новой учетной записи. То же самое, если я войду в систему с правильным именем пользователя. Что я делаю не так? (я довольно новичок, и это моя первая наполовину приличная программа, поэтому, пожалуйста, не будьте слишком суровы, если я делаю что-то явно неправильно.)

Су. Я сделал некоторые из тех вещей, которые я понял. Это то, что я получил сейчас: НО теперь он не будет записывать новое имя пользователя в файл Usernames_and_passwords. я невероятно смущен…

 #include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
#include <fstream>

using namespace std;

string user_input;
string birth_year;
string user_age;
string current_user_profile, current_user_password;
string username, password;
string newprofile;
string makenewusername, makenewpassword;

void TalkToAi() { //VOID TALKTOAI
    while (true) {
        cout << "write something: ";
        cin >> user_input;
            transform(user_input.begin(), user_input.end(), user_input.begin(), ::tolower); //TRANSLATES ALL UPPERCASE LETTERS TO LOWER CASE SO THE SYSTEM CAN UNDERSTAND!
        cout << user_input << "n"; //###FOR TESTING PORPOSES!!!###

        //IF LIBRARY!

        if (user_input == "what's my age?" || user_input == "count my age" || user_input == "whats my age?") {
            //###CONTINUE HERE!!!###
        }

    }
}

void StartUp() { //VOID UPONSTARTUP (WHAT TO DO, ALSO READS DIFFRENT PROFILES AND PASSWORDS FOR LOGIN)
    cout << "what profile should i load?" << "n" << "profile name: ";
    cin >> current_user_profile;

    fstream Myfile;
    Myfile.open("Usernames_and_passwords.txt");

    if (Myfile.is_open()) {
        while (getline (Myfile, username) ) {
            if (username == current_user_profile) {
                cout << "n" << "Hello, " << username << "n";
                break;
                }
                }
        if (username != current_user_profile) {
            cout << "wrong username or username unfortunately not found.n";
            cout << "shall i create a new profile? Yes/No: ";
            cin >> newprofile;
            if (newprofile == "Yes" || newprofile == "yes") {
                cout << "new profile username: ";
                cin >> makenewusername;
                Myfile << makenewusername << endl;
            }
        }
    }
}
  

Комментарии:

1. Комментарии типа «// CALLS VOID STARTUP» довольно бесполезны, поскольку мы уже можем видеть это, просто прочитав код. Добавьте комментарии и документацию для вещей, которые не очевидны.

2. Что касается вашей проблемы, я рекомендую немного отладки rubber duck , а вам просто сесть и немного подумать о своем дизайне и его реализации.

3. хорошо, я попытаюсь разобраться в этом, и я знаю, что это немного бесполезно. Но я просто не хочу делать ошибки начинающих, делая код очень трудным для понимания.

4. Некоторые вещи, о которых следует подумать для решения проблемы в этом вопросе: 1) Что вам следует делать, когда вы сопоставляете имя пользователя в файле? Вы действительно должны продолжать чтение из файла? 2) Вы действительно должны проверить, не найден ли пользователь внутри цикла? 3) Действительно ли вы должны записывать в файл в середине его? Возможно, вам следует открыть его дважды (один раз для чтения и один раз для записи)? 4) Не используйте глобальные переменные. Особенно, если они даже не разделяются между функциями.

5. @GottaAimHigherPal Я бы порекомендовал вам начать с более простых упражнений, чтобы изучить основы функций и базовой организации кода. Затем вы можете продолжить управление файлами и т. Д.

Ответ №1:

Он не будет записывать в файл, потому что, как только вы закончите чтение файла с помощью getline(), будет установлен флаг eof . Вам нужно открыть файл с помощью:

Myfile.open("Usernames_and_passwords.txt",fstream::in | fstream::out | fstream::app);

Это говорит программе открыть файл для чтения и записи. fstream::app сообщает программе добавить текст в конец файла.

Затем, чтобы сбросить значение после нажатия eof, вы можете сделать

 Myfile.clear();
Myfile.seekg(0, ios::beg);  
  

Это снимет флаг eof и переместит указатель обратно в начало файла.
После этого вы можете записать в файл.

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

Вот модифицированная версия вашей функции:

 void StartUp() { //VOID UPONSTARTUP (WHAT TO DO, ALSO READS DIFFRENT PROFILES AND PASSWORDS FOR LOGIN)
    cout << "what profile should i load?" << "n" << "profile name: ";
    cin >> current_user_profile;

    fstream Myfile; 
    Myfile.open("Usernames_and_passwords.txt",fstream::in | fstream::out | fstream::app);   

    if (Myfile.is_open()) {
        while (getline (Myfile, username) ) {
            if (username == current_user_profile) {
                cout << "n" << "Hello, " << username << "n";
                return;
                }
        }

        cout << "wrong username or username unfortunately not found.n";
        cout << "shall i create a new profile? Yes/No: ";
        cin >> newprofile;
        if (newprofile == "Yes") {
            cout << "new profile username: ";
            cin >> makenewusername;         
            Myfile.clear();
            Myfile.seekg(0, ios::beg);                  
            Myfile << makenewusername << endl;  
        }   
    }
}
  

Я бы также предложил разрешить StartUp возвращать логическое значение о том, удалась операция или нет, чтобы вы могли решить завершить программу. Например. если пользователь ввел «Нет».

Комментарии:

1. «Вы не закрываете файл, как только закончите с ним» Вообще неверно; .close() вызов является избыточным , и файл будет закрыт, когда поток выйдет из области видимости.

2. Спасибо, не знал об этом. Отредактировал мой ответ.

3. Большое спасибо за вашу помощь. Я не знал, что сообщество было настолько полезным!