I've been making a program for fun and I'm an amateur programmer too. I added a feature to a program that let's it read users externally from files to log in instead of storing user data on the code so that new users can register.

I'm having problems in line 13 and 14 when putting the root of where the user files are where /" makes the ; become part of the string too and invalid.

Also, in line 40 it gives me the error of invalid conversion between const char* to char, please help me!

Last bu not least, how can make it so that the files with user names and passwords and secret and no one can see them and can it work if I don't put .txt in the end of the file name?

#include <iostream>
#include <cstring>
#include <conio.h>
#include <fstream>

using namespace std;

void calc();
void loop();
void fbase();
char user[25];
char pass[25];
char userpath[30] = "user\";
char userpasspath[30] = "user\";
int u = 0;

int main()
{
    cout<<"Cenu Alpha v0.2\n\n";
    for ( ; u == 0; u++) {
        cout<<"User: ";
        cin>>user;
        strcat (userpath, user);
        strcat (userpasspath, user);
        strcat (userpasspath, "pass");
        ifstream userfile ( userpath );
        ifstream userpassfile ( userpasspath );
        if (userfile == user) {
            cout<<"Password: ";
            cin>>pass;
            if (pass == userpassfile) {
                cout<<"\nWelcome, signed in as "<< user <<".\n\n";
            } else {
                cout<<"Wrong password. Quitting...";
                getch();
                return 0;
            }
        } else {
            cout<<"\nUser unkown, signed in as guest.\n\n";
            user[0] = "g";
        }
    }
    int choice;
    cout<<"What would you like to use?\n\n";
    cout<<"1. Calculator\n";
    cout<<"2. Function Database\n";
    cout<<"3. Exit\n\n";
    cout<<"Selection: ";
    cin>>choice;
    cout<<endl;
    cin.ignore();
    switch (choice) {
        case 1:
            calc();
            break;
        case 2:
            fbase();
            break;
        case 3:
            cout<<"Thank you for running Cenu Alpha v0.2!";
            break;
        default:
            cout<<"Invalid selection. Please try again.\n\n";
            main();
            break;
    }
    cin.get();
}

void calc()
{
    int num1;
    int num2;
    cout<<"Calculator\n\nFirst Number: ";
    cin>>num1;
    cin.ignore();
    cout<<"Second Number: ";
    cin>>num2;
    cin.ignore();
    cout<<endl<<num1<<"+"<<num2<<"="<<num1+num2<<"\n";
    getch();
    main();
}

void fbase() {
    int choice;
    cout<<"Function Database\n";
    cout<<"Welcome to the funcion database. It contains complex forgetable functions.\n\n";
    cout<<"1. String Functions\n";
    cout<<"2. Other general funcions\n";
    cout<<"3. Back\n\n";
    cout<<"Selection: ";
    cin>>choice;
    cout<<"\n";
    switch (choice) {
        case 1:
            cout<<"1. #include <cstring>\n";
            cout<<"2. int strcmp( string, string)\n";
            cout<<"3. char strcat( destination, source)\n";
            cout<<"4. char strcpy( destination, source)\n";
            cout<<"5. size_t strlen( source)\n\n";
            cout<<"Selection: ";
            cin>>choice;
            cout<< endl;
            switch (choice) {
                case 1:
                    cout<<"#include <cstring>\n";
                    cout<<"This is the header file for many string funcions.\n\n";
                    getch();
                    fbase();
                    break;
                case 2:
                    cout<<"int strcmp( string 1, string 2)\n";
                    cout<<"Negative if s1 is less than s2.\n";
                    cout<<"Zero if s1 and s2 are equal.\n";
                    cout<<"Positive if s1 is greater than s2.\n\n";
                    getch();
                    fbase();
                    break;
                case 3:
                    cout<<"char strcat( destination, source)\n";
                    cout<<"Must if string is char: charname[0] = '\0'\n";
                    cout<<"Adds source to end of destination.\n\n";
                    getch();
                    fbase();
                    break;
                case 4:
                    cout<<"char strcpy( destination, source)\n";
                    cout<<"Makes destination same as source. (Untested)\n\n";
                    getch();
                    fbase();
                    break;
                case 5:
                    cout<<"int size_t strlen( source)\n";
                    cout<<"Resturns the length of the source string.\n\n";
                    getch();
                    fbase();
                    break;
                default:
                    cout<<"Invalid selection. Please try again.\n\n";
                    getch();
                    fbase();
                    break;
            }
            break;
        case 2:
            cout<<"1 = True. 0 = False";
            cout<<"Not (!). False to true and true to false.\n";
            cout<<"And (&). If both are right, return 1, if not, then false.\n";
            cout<<"Or (||). If any of the numbers are 1, return 1.\n";
            getch();
            fbase();
            break;
        case 3:
            main();
            break;
        default:
            cout<<"Invalid selection. Please try again.\n\n";
            getch();
            fbase();
            break;
    }
}

If you want to use a \ in a string do two of them back to back like "user\\".
Line 40 use 'g'. When you want a char you have to use ' not " which is for a string.

Edited 4 Years Ago by histrungalot: Line 40

As far as storing values in a file (or in a database on a server), it's a good idea to use an encryption scheme to store something like a password. You can't make the file otherwise readable to your program, but unreadable to everyone else. And if you could, you definitely shouldn't trust that you've done it right. There are reversible encryption schemes (so if the user forgets his password, you can decrypt the encrypted data and tell him what it is), though stronger schemes are one-way: if the user forgets his password, you can't recover it for him; instead, you assign him a new temporary password and tell him what that is, and hope he's smart enough to change it something he can remember (or else force him to do so before he can continue). In this way, if anyone gets hold of the file (or gets into the database), they theoretically can't determine what anybody's actual password is(*). With a one-way scheme, you verify the login by encrypting the password provided by the user and checking whether that matches the encrypted password stored in the file/database.

(*) There are plenty of exceptions to this, I won't go into them here....

For communicating with a remote server, further encryption (using something like SSL) is used to make sure anyone watching the data go back and forth can't get either the raw password or the encrypted password in a state where they could use it to access the user's account.

Also, you should be able to name your file whatever you want. Putting .txt at the end just allows "default programs" (like a text-editor in this case) to be started automatically when you double-click on it.

One more problem. In the last two lines of code, you can see it. This is the new piece of code I made to make a new user. How can I put text inside the file without using cin <<? Also, how can a make a encryption system?

} else if (user == "new user") {
            char newuser[25];
            char newpass[25];
            char path[30] = "user\\";
            char passpath[30] = "user\\";
            cout<<"\nNew user's name: ";
            cin>>newuser;
            cout<<"New user's password: ";
            cin>>newpass;
            char passuserpath[30];
            strcat(passuserpath, newuser);
            strcat(path, newuser);
            strcat(passuserpath, "pass");
            strcat(passpath, passuserpath);
            ofstream newuserpath ( path );
            ofstream newuserpasspath ( passpath );
            newuserpath = newuser;
            newuserpasspath = newpass;

I'm not sure why you'd want your username and password in separate files, keeping them properly synchronized would seem nearly impossible.

ofstream userstream ( path, ios_base::app );
...
userstream << newuser << " " << encrypt(newpassword) << endl;

cplusplus.com is a great reference site!

Read up on encryption options in general (Wikipedia is probably a reasonable place to start), and Google "C++ encryption". You're not likely to want to "make" an encryption system. The systems are there and written for you, just hook them in and use them (download whatever you don't already have, include the correct header file(s), and link against the correct library(ies)).

Well, I have them in two different files because I only know how to read the first word of a file. How can I keep them in one file? Also, I'll worry about the encryption after I do the single file system and also. I get a weird error that everything repeats before it crashes when I type new user in the user slot. Can you help me on that? Here is the code, try compiling it and running it and typing new user as the user:

#include <iostream>
#include <cstring>
#include <conio.h>
#include <fstream>

using namespace std;

void calc();
void loop();
void fbase();
char user[25];
char pass[25];
char userpath[30] = "user\\";
char userpasspath[30] = "user\\";
int u = 0;

int main()
{
    cout<<"Cenu Alpha v0.2\n\n";
    for ( ; u == 0; u++) {
        cout<<"User: ";
        cin>>user;
        strcat (userpath, user);
        strcat (userpasspath, user);
        strcat (userpasspath, "pass");
        ifstream userfile ( userpath );
        ifstream userpassfile ( userpasspath );
        if (userfile == user) {
            cout<<"Password: ";
            cin>>pass;
            if (pass == userpassfile) {
                cout<<"\nWelcome, signed in as "<< user <<".\n\n";
            } else {
                cout<<"Wrong password. Quitting...";
                getch();
                return 0;
            }
        } else if (user == "new user") {
            char newuser[25];
            char newpass[25];
            char path[30] = "user\\";
            char passpath[30] = "user\\";
            cout<<"\nNew user's name: ";
            cin>>newuser;
            cout<<"New user's password: ";
            cin>>newpass;
            char passuserpath[30];
            strcat(passuserpath, newuser);
            strcat(path, newuser);
            strcat(passuserpath, "pass");
            strcat(passpath, passuserpath);
            ofstream newuserpath ( path );
            ofstream newuserpasspath ( passpath );
            newuserpath << newuser;
            newuserpasspath << newpass;
        } else {
            cout<<"\nUser unkown, signed in as guest.\n\n";
            user[0] = 'g';
        }
    }
    int choice;
    cout<<"What would you like to use?\n\n";
    cout<<"1. Calculator\n";
    cout<<"2. Function Database\n";
    cout<<"3. Exit\n\n";
    cout<<"Selection: ";
    cin>>choice;
    cout<<endl;
    cin.ignore();
    switch (choice) {
        case 1:
            calc();
            break;
        case 2:
            fbase();
            break;
        case 3:
            cout<<"Thank you for running Cenu Alpha v0.2!";
            break;
        default:
            cout<<"Invalid selection. Please try again.\n\n";
            main();
            break;
    }
    cin.get();
}

void calc()
{
    int num1;
    int num2;
    cout<<"Calculator\n\nFirst Number: ";
    cin>>num1;
    cin.ignore();
    cout<<"Second Number: ";
    cin>>num2;
    cin.ignore();
    cout<<endl<<num1<<"+"<<num2<<"="<<num1+num2<<"\n";
    getch();
    main();
}

void fbase() {
    int choice;
    cout<<"Function Database\n";
    cout<<"Welcome to the funcion database. It contains complex forgetable functions.\n\n";
    cout<<"1. String Functions\n";
    cout<<"2. Other general funcions\n";
    cout<<"3. Back\n\n";
    cout<<"Selection: ";
    cin>>choice;
    cout<<"\n";
    switch (choice) {
        case 1:
            cout<<"1. #include <cstring>\n";
            cout<<"2. int strcmp( string, string)\n";
            cout<<"3. char strcat( destination, source)\n";
            cout<<"4. char strcpy( destination, source)\n";
            cout<<"5. size_t strlen( source)\n\n";
            cout<<"Selection: ";
            cin>>choice;
            cout<< endl;
            switch (choice) {
                case 1:
                    cout<<"#include <cstring>\n";
                    cout<<"This is the header file for many string funcions.\n\n";
                    getch();
                    fbase();
                    break;
                case 2:
                    cout<<"int strcmp( string 1, string 2)\n";
                    cout<<"Negative if s1 is less than s2.\n";
                    cout<<"Zero if s1 and s2 are equal.\n";
                    cout<<"Positive if s1 is greater than s2.\n\n";
                    getch();
                    fbase();
                    break;
                case 3:
                    cout<<"char strcat( destination, source)\n";
                    cout<<"Must if string is char: charname[0] = '\0'\n";
                    cout<<"Adds source to end of destination.\n\n";
                    getch();
                    fbase();
                    break;
                case 4:
                    cout<<"char strcpy( destination, source)\n";
                    cout<<"Makes destination same as source. (Untested)\n\n";
                    getch();
                    fbase();
                    break;
                case 5:
                    cout<<"int size_t strlen( source)\n";
                    cout<<"Resturns the length of the source string.\n\n";
                    getch();
                    fbase();
                    break;
                default:
                    cout<<"Invalid selection. Please try again.\n\n";
                    getch();
                    fbase();
                    break;
            }
            break;
        case 2:
            cout<<"1 = True. 0 = False";
            cout<<"Not (!). False to true and true to false.\n";
            cout<<"And (&). If both are right, return 1, if not, then false.\n";
            cout<<"Or (||). If any of the numbers are 1, return 1.\n";
            getch();
            fbase();
            break;
        case 3:
            main();
            break;
        default:
            cout<<"Invalid selection. Please try again.\n\n";
            getch();
            fbase();
            break;
    }
}
  1. You can not do else if (user == "new user") . user is a char *, if it was a C++ string you could. For this check to work you would have to do else if (strcmp(user,"new user") == 0)
  2. You don't want to call main() in your code. main() should only be used as an entrance to the program from the OS.
  3. You want to read the contents of the file and check it against the user name, not check the ifstream object with the user name ( if (userfile == user) ). Surprised that compiled.
  4. Since you are using C++ you should use C++ string in place of arrays of chars.
  5. If you are trying to read "new user", the cin >> user will stop reading at the space and user will be "new". In this case you might want to use getline.

Below is some code, user file and output. Take a look to see what I mean by some of the above.

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
const string logInInfo("./users");

bool checkUser(string u, string &password){
  string user,pass;
  bool   ret(false);
  ifstream inStrm(logInInfo.c_str());
  while (!ret && inStrm >> user >> pass ){
     if ( user == u ){
        password = pass;
        ret = true;
     }
  }
  inStrm.close();
  return ret;
}

int main(){
  string user,userPass;
  size_t pos;
  cout<<"Cenu Alpha v0.2\n\n";
  cout << "User: ";
  getline(cin,user); 
  if ( (pos = user.find("new user")) != string::npos ){
     // do something
     cout << "Need to add user!" << endl;
  }
  else if ( checkUser(user,userPass) ) {
     string pass;
     cout << "password: ";
     cin >> pass;
     cin.ignore(numeric_limits<int>::max(),'\n');
     if ( pass == userPass ) {
        cout << "\nWelcome, signed in as "<< user <<".\n\n";
     } else {
        cout<<"Wrong password. Quitting..." << endl;
     } 
  }
  else {
     cout<<"\nUser unkown, signed in as guest.\n\n" << endl;
     user = "g";
  }
  return 0;
}
$ cat users 
user1 catsAndDogs
user2 things1234
root  admin

Output:

$ ./a.out
Cenu Alpha v0.2

User: root
password: admin

Welcome, signed in as root.

$ ./a.out
Cenu Alpha v0.2

User: root
password: notIt            
Wrong password. Quitting...
$ ./a.out
Cenu Alpha v0.2

User: new user
Need to add user!
$

Sorry for the long time it took me to read your post. Before I use that piece of code, can you explain to me what the new lines do because I'm not very good at C++ and I don't understand the piece of code you put? Can you explain it to me please?

Thanks,
funkey100

I put comments in the code. If you have more questions, tell the line number and I will try to expand.

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

//------------------------------------------------------
// Define a constant variable that holds the name of 
// the file that is going to be used to hold the 
// user information.  Its constant because we don't 
// want to ever change the value of that variable.
const string logInInfo("./users");

//------------------------------------------------------
// 
// Function:  checkUser() 
//
// Description: This function is used to check and see
//              if a user is in the file of users of
//              the system.  
// 
// Input:
//   string u:  Name of user we want to search for.
//
// Output:
//   string password: The password of the user passed
//                    in if found.
// Return:
//   bool:  Returns true if user is found and false if not
//
bool checkUser(string u, string &password){
  //------------------------------------------------------
  // Local variables 
  string user,pass;

  //------------------------------------------------------
  // Set the default value of the return to false
  bool   ret(false);

  //------------------------------------------------------
  // Open the file that contains the username and passwords
  ifstream inStrm(logInInfo.c_str());

  //------------------------------------------------------
  // While we have not found the user and there are 
  // not file read errors, check to see if the user we
  // passed in matches one of the users we are reading
  // out of the users file.
  while (!ret && inStrm >> user >> pass ){
     //------------------------------------------------------
     // Check to see if the user in the file equals the
     // user name we passed into the function.
     // Because user and u are C++ strings you can use 
     // == to check if the two values are equal.  This
     // is not the case with C strings.
     // Read about strings:
     //    http://www.cplusplus.com/reference/string/string
     if ( user == u ){
        //------------------------------------------------------
        // If user in the file matches user passed into the
        // function, set the password of that user to password
        // variable to be passed out
        password = pass;
        //------------------------------------------------------
        // Set the return value to true to indicate user was 
        // found and to stop looking in the file.  If we have
        // found the user then there is no need to continue to
        // to look in the file.  Being that user names are unique.
        ret = true;
     }
  }
  //------------------------------------------------------
  // Close the input file
  inStrm.close();
  //------------------------------------------------------
  // Return if the user passed was found
  return ret;
}

//------------------------------------------------------
// 
// Function:  main() 
// 
// Description: This program takes a user name and password
//              from a user and checks to see if they are
//              in a file of approved user.
// 
int main(){
  string user,userPass;
  size_t pos;
  cout<<"Cenu Alpha v0.2\n\n";
  cout << "User: ";
  //------------------------------------------------------
  // Need to use getline because if you use cin >> user
  // it only reads in one string and you won't be able to
  // check for "new user"
  // Read about getline:
  //     http://www.cplusplus.com/reference/string/getline
  getline(cin,user); 

  //------------------------------------------------------
  // Check to see if the user entered is equal to "new user"
  if ( user == "new user" ){
     //------------------------------------------------------
     // do something
     cout << "Need to add user!" << endl;
  }
  //------------------------------------------------------
  // If the user was not "new user", then check to see if
  // the user entered is a user that we have in our file
  // of users.  If found the users password in returned
  // in the variable userPass so we can check it later.
  else if ( checkUser(user,userPass) ) {
     string pass;
     //------------------------------------------------------
     // Ask the user for there password and save it
     cout << "password: ";
     cin >> pass;
     //------------------------------------------------------
     // This line is to get rid of the newline at the end
     // of the line because cin >> pass will not remove it
     // out of the input stream.
     // Read about this:
     //    http://www.cplusplus.com/doc/tutorial/basic_io  
     cin.ignore(numeric_limits<int>::max(),'\n');

     //------------------------------------------------------
     // Check to see if the password entered is equal to 
     // the password stored in the user file
     if ( pass == userPass ) {
        cout << "\nWelcome, signed in as "<< user <<".\n\n";
     } else {
        cout<<"Wrong password. Quitting..." << endl;
     } 
  }
  else {
     //------------------------------------------------------
     // If not a "new user" and not a user in the users file
     // let them in as a guest
     cout<<"\nUser unkown, signed in as guest.\n\n" << endl;
     //------------------------------------------------------
     // Set user to guest
     user = "g";
  }
  return 0;
}
This article has been dead for over six months. Start a new discussion instead.