-1

Ok so I am trying to write a program that takes in passwords and usernames to store them in a file (I haven't written the part where they write to the file yet and will do that later), but the part of my code that reads the files causes it to not work (no output) even though it compiles with no error in VS code. To be honest, I do not completely understood what I wrote either (I just followed a youtube video), so I must be missing something about the code. For extra information I am using C++ 20 and clang++ as my compiler. I have posted my code below for reference.

#include <iostream>
#include <cstdio>
#include <vector>
#include <fstream>


using namespace::std;

class user {
    private:
        string username;
        string password;
    public:
        user(string user, string pass) {
            username = user;
            password = pass;
        }
        void SetUsername(string user) {
            username = user;
        }
        void SetPassword(string pass) {
            password = pass;
        }
        void ChangeUsername(string user) {
            username = user;
        }
        void ChangePassword(string pass) {
            password = pass;
        }
        string GetUsername() {
            return username;
        }
        string GetPassword() {
            return password;
        }
        
        

};

int main() {
    string listUsernames[1000];
    string listPasswords[1000];
    vector <user>list;
    string username;
    string password;
    string prompt;
    bool loginSuccess = false;
    bool success = false;
    int counter = 0;
    int lines = 0;

    /*
    This part is like messsing it up
    Starting from here:
    */
    ifstream file;
    file.open("usernames.txt");
    while(!file.eof()) {
        getline(file, listUsernames[lines]);
        lines++;
    }
    file.close();


    lines = 0;
    file.open("passwords.txt");
    while(!file.eof()) {
        getline(file, listPasswords[lines]);
        lines++;
    }
    file.close();

    for(int i = 0; i < lines; i++) {
        user oldUser(listUsernames[i], listPasswords[i]);
        list.push_back(oldUser);
    }
    /*
    Ending here
    */

    cout << "\tWelcome user! Please choose to login or create an account below.\n";
    do{
    cout << "\tType \"Login\" to login or \"Create\" to create a new account\n";
    cin >> prompt;
        if(prompt == "Login") {
            do{
                cout << "Username: ";
                cin >> username;
                cout << "Password: ";
                cin >> password;

                for(int i = 0; i < list.size(); i++) {
                    if(username == list[i].GetUsername() && password == list[i].GetPassword()) {
                        cout << "Hello " << list[i].GetUsername() << "!\n\n";
                        loginSuccess = true;
                        success = true;
                    }
                }
                if(!loginSuccess) {
                    cout << "Incorrect username or password";
                    counter++;
                    if(counter < 2) {
                        cout << ", please try again.\n";
                    }
                    else {
                        cout << "\nMaybe you should try creating an account! \n";
                    }
                }
            } while(!loginSuccess && counter < 2);
        }
        else if(prompt == "Create") {
            string newUsername;
            string newPassword;
            cout << "What would you like your username to be? Please enter: ";
            cin >> newUsername;
            cout << "What would you like your password to be? Please enter: ";
            cin >> newPassword;  
            user newUser(newUsername, newPassword);
            list.push_back(newUser);
            cout << "Success!\n";
            ofstream myfile;
            myfile.open("usernames");
            myfile << newUsername;
            myfile.close();
            myfile.open("passwords");
            myfile << newPassword;
            myfile.close();
        }
        else {
            cout << "Sorry, that input was not understood\n";
            cout << "Please try again\n";
        }
    } while(!success);
    return 0;
}
  • 6
    Side note: I suggest that you learn C++ from [a good book](https://stackoverflow.com/q/388242/12149471) instead of from YouTube videos. – Andreas Wenzel Mar 10 '23 at 03:55
  • In addition to what @AndreasWenzel wrote, your entire approach is backward. If you don't write the code to write to the file first, what file are you going to be reading from? Also, *compiles without errors* just means that the syntax is correct - it does not mean that there are no logic errors. Use the debugger to step through the code to trace the execution path and see what's actually happening when the code runs. – Ken White Mar 10 '23 at 03:58
  • do the files `usernames.txt` and `passwords.txt` exist? `file.eof` checks if you've read to the end of the file, if you haven't read at all because the file doesn't exist then it returns false. You have an infinite loop waiting to read to the end of a file that doesn't exist. – Daniel Garcia Mar 10 '23 at 03:58
  • 5
    If the Youtube video told you to write `while(!file.eof()) {`, then I suggest that you stop using that video as a reference. Here is an explanation why this approach is generally wrong: [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/q/5605125/12149471) – Andreas Wenzel Mar 10 '23 at 03:59
  • @DanielGarcia They do exist and each have one username/password in them as a test (they are in the same workspace and folder as the code file in VS code) – DoubleAWsmile Mar 10 '23 at 04:04
  • @KenWhite I honestly have no clue how to use the debugger console. Usually it gives me an error but this time it just doesn't post anything in the terminal or debugger console and no error occurs. – DoubleAWsmile Mar 10 '23 at 04:06
  • is the compiled program you're running in the same folder as those 2 files? – Daniel Garcia Mar 10 '23 at 04:08
  • @DoubleAWsmile: If your program is using input, then please post this input - or at least a [mre] of this input - into the question as text. – Andreas Wenzel Mar 10 '23 at 04:08
  • @AndreasWenzel Ok, I will try to rewrite it without the .eof. As for the book, I just picked up C++ today and ordered some books on amazon (but they arrive in a few days unfortunately), so I am watching some youtube videos as coding has been pretty fun. – DoubleAWsmile Mar 10 '23 at 04:09
  • @DanielGarcia yes – DoubleAWsmile Mar 10 '23 at 04:09
  • 4
    I didn't say *debug console*. I said **the debugger**, which is a tool that allows you to execute the code line-by-line so you can step through to see what it's doing, evaluate the values of variables, and trace the actual execution flow of the code. If you don't know how to use it, now is an excellent time to start learning. There's no better tool available to a programmer. – Ken White Mar 10 '23 at 04:12
  • Are you running through vscode or some other way? Try `cd`ing to the folder and running it. I ask because I was able to get output when running it with those two files present, but if it can't find them because they're not in the current working directory them you get thr blank infinite loop. – Daniel Garcia Mar 10 '23 at 04:12
  • 2
    I suggest that you read this: [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/q/25385173/12149471) You may also want to read this: [How to debug small programs?](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) – Andreas Wenzel Mar 10 '23 at 04:13
  • @DanielGarcia Thank you, this is probably the reason why. I will try to figure out how to cd them to the folder – DoubleAWsmile Mar 10 '23 at 04:26
  • 1
    Before proceeding after attempting to open the file, your program should first verify that the file was successfully opened. If opening the file failed, then the program should print an error message and terminate. One simple way of doing this is to add `if ( !file ) { cerr << "Error opening file!\n"; return 1; }` immediately after the line `file.open("passwords.txt");`. – Andreas Wenzel Mar 10 '23 at 04:34
  • Note that I have reposted my last comment, because my original comment had an error. I had originally written `if ( file )`, but the new reposted comment now correctly states `if ( !file )`. I had forgotten to write the `!`. – Andreas Wenzel Mar 10 '23 at 04:35
  • 2
    A good rule when writing code in any language is to start with something small and simple that works perfectly, then enlarge it in small steps. After `HelloWorld`, you should write a program that tries to open an input file, and reports success or failure; don't try anything more complex until that works perfectly. If you write a hundred lines before testing anything, your code will not work. – Beta Mar 10 '23 at 05:11
  • 1
    Apparently usernames with no extension at the end is not the same as usernames.txt. I thought that because I was on a macbook that finder just displayed txt files with no extensions but the problem was solved by just changing usernames and passwords to usernames.txt and passwords.txt – DoubleAWsmile Mar 10 '23 at 05:44
  • Very sorry for the inconvenience – DoubleAWsmile Mar 10 '23 at 05:46
  • @Beta I just added those lines at the time of writing the post so surprisingly I have been following the rule but thank you for your advice regardless. – DoubleAWsmile Mar 10 '23 at 05:47

2 Answers2

0

Your mistakes:

  • You are writing to files "username" and "passwords" and reading from "usernames.txt" and "passwords.txt".
  • You are checking while (!file.eof()) which is incorrect (link)

After fixes:

ifstream file;
file.open("usernames");
while(getline(file, listUsernames[lines])) {
    lines++;
}
file.close();


lines = 0;
file.open("passwords");
while(getline(file, listPasswords[lines])) {
    lines++;
}
file.close();
kiner_shah
  • 3,939
  • 7
  • 23
  • 37
0
#include <iostream>
#include <cstdio>
#include <vector>
#include <fstream>
#include <cassert>

struct User
{
    std::string username;
    std::string password;
};

std::vector<std::string> from_file(const std::string& file_name)
{
    auto content = std::vector<std::string>{};
    auto line = std::string{};
    auto file = std::ifstream{file_name};
    while(getline(file, line)) {
        content.emplace_back(std::move(line));
    }
    return content;
}

bool login( const std::vector<User>& users )
{
    constexpr auto max_retry = 2;
    auto counter = 0U;
    while(counter < max_retry)
    {
        auto username = std::string{};
        auto password = std::string{};
        std::cout << "Username: ";
        std::cin >> username;
        std::cout << "Password: ";
        std::cin >> password;

        for(const auto& user : users) {
            if(user.username == username && user.password == password) {
                std::cout << "Hello " << username << "!\n\n";
                return true;
            }
        }

        std::cout << "Incorrect username or password";
        ++counter;
        if(counter < max_retry) {
            std::cout << ", please try again.\n";
        }
        else {
            std::cout << "\nMaybe you should try creating an account! \n";
        }
    }
    return false;
}

constexpr auto usernames_file = "usernames.txt";
constexpr auto passwords_file = "passwords.txt";

bool create(std::vector<User>& users)
{
    auto username = std::string{};
    auto password = std::string{};
    std::cout << "What would you like your username to be? Please enter: ";
    std::cin >> username;
    std::cout << "What would you like your password to be? Please enter: ";
    std::cin >> password;
    users.emplace_back(User{username, password});
    std::cout << "Success!\n";
    {
        auto file = std::ofstream{usernames_file};
        file << username;
    }
    {
        auto file = std::ofstream{passwords_file};
        file << password;
    }
    return true;
}

int main()
{
    auto list_usernames = from_file(usernames_file);
    auto list_passwords = from_file(passwords_file);

    assert(list_usernames.size() == list_passwords.size());

    auto users = std::vector<User>{};
    for(auto i = 0; i < list_usernames.size(); ++i)
    {
        users.emplace_back(User{list_usernames[i], list_passwords[i]});
    }

    std::cout << "\tWelcome user! Please choose to login or create an account below.\n";
    auto success = false;
    while(!success)
    {
        std::string prompt;
        std::cout << "\tType \"Login\" to login or \"Create\" to create a new account\n";
        std::cin >> prompt;
        if(prompt == "Login")
        {
            success = login(users);
        }
        else if(prompt == "Create")
        {
            success = create(users);
        }
        else
        {
            std::cout << "Sorry, that input was not understood\n";
            std::cout << "Please try again\n";
        }
    }
    return 0;
}
thebugger
  • 123
  • 6