Search code examples
c++passwordsaccountofstream

creating a .txt in a variable directory


I might change this later to a better form of databasing, and if you have any advice on that then shoot, I'm pretty new to C++ and I am currently thinking JSON because I used it a bit in Python. For now though I am just looking to test and make sure everything works.

Here is my issue, earlier I created a function to create a directory to store account information in. Now I am working on storing passwords in the account directory. Here is what I got:

cout<<"Type 'NEW' to create an account or enter your account name.\n";
cout<<"Account Name: ";
cin>> account;
cin.ignore();
if (account == "New" or account == "NEW" or account == "new"){
    string accname;
    cout<<" \n";
    cout<<"Please enter your desired Account Name: ";
    cin>> accname;
    cin.ignore();
    if (accname.length() > 2){
        std::string yesOrno;
        cout<<" \n";
        cout<<"You have chosen, '" << accname << "' as your Account Name, correct? ";
        cin>> yesOrno;
        cin.ignore();
        if (yesOrno == "Yes" or yesOrno == "YES" or yesOrno == "yes" or yesOrno == "y"){
        system(("mkdir -p /home/user/Program/accounts/"+accname).c_str());
        cout<<" \n";
        cout<<"It is advised to select a strong password for your account. Such as a phrase ins\n";
        cout<<"tead of a word and/or using special characters, numbers, and letters. We require\n";
        cout<<"it to be at least six characters long for security reasons.\n";
        cout<<" \n";
        std::string str1;
        std::string str2;
        cout<<"Please select a password: ";
        cin>> str1;
        cin.ignore();
        cout<<"Please retype your password: ";
        cin>> str2;
        cin.ignore();
        if (str1 == str2){
            ofstream password;
            password.open("/home/user/Program/accounts/"+accname+"password.txt");
            password.close();
        }
        else {
            cout<< "Passwords do not match.";
             }
        }
    }
    else {
        cout<<"That is too short, please choose another Account Name: ";
    }
}

Now the issue is that as above I get an error when compiling:

intro.cpp: In function ‘int main()’:
intro.cpp:66:72: error: no matching function for call to ‘std::basic_ofstream<char>::open(std::basic_string<char>)’
     password.open("/home/user/Program/accounts/"+accname+"password.txt");
                                                                        ^
intro.cpp:66:72: note: candidate is:
In file included from intro.cpp:2:0:
/usr/include/c++/4.8/fstream:713:7: note: void std::basic_ofstream<_CharT, _Traits>::open(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits<char>; std::ios_base::openmode = std::_Ios_Openmode]
       open(const char* __s,
       ^
/usr/include/c++/4.8/fstream:713:7: note:   no known conversion for argument 1 from ‘std::basic_string<char>’ to ‘const char*’

Which I have no clue what that means.

So then I tried the password part as so:

password.open("/home/user/Program/accounts/password.txt");

And that worked in that it compiled and created the .txt, but it isn't creating the file specifically where I wanted it. Is there a way to do this? Am I on the right track?


Solution

  • The problem here is that std::basic_ofstream::open does not have an overload which accepts std::string, in C++03. However, in C++11, the overloads of open are:

    void open( const char *filename,
               ios_base::openmode mode = ios_base::out );
    void open( const std::string &filename,                                  
               ios_base::openmode mode = ios_base::out );
    

    So, your original code should work fine if you add the -std=c++11 to the compiler command line when building your code.

    The other problem is that you are missing a slash. This is one of the reasons that you should use a dedicated library for manipulating filesystem objects, such as Boost.Filesystem.

    The missing slash is right after you append accname:

    password.open(("/home/user/Program/accounts/"+accname+"/password.txt").c_str());
    

    And again, if you add -std=c++11, then you don't need to use c_str() here, e.g. the fix becomes:

    password.open("/home/user/Program/accounts/"+accname+"/password.txt");