#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. Большое спасибо за вашу помощь. Я не знал, что сообщество было настолько полезным!