Hi Cplusplus forum coders!
My assignment is to extend the class I wrote in Assignment 2 (code below) by reading the configuration
file provided and enforcing password policy based on the contents of the file. Specifically, the
program must read the file and act in accordance to it. The "content" parts of the file are in the
format:
key = value
...where "key" is some configuration option, and "value" is the associated value for my
program to enforce. Any line starting "#" or any blank line should be ignored.
The program must find the key "Attempts". The value associated with key should be an
integer, representing the number of times a user may attempt to enter a combination of user ID
and password before the program gives up on the user. If this configuration key/value pair is
missing or invalid, it should be defaulted to 3.
This was my program 2.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
// This program will accept user ID and password from user and match
// with one on file lab2.data If pass and user match then program
// will display a success message.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
class PasswordSystem
{
public:
//function that will be executed when program is run
void login()
{
string user;
string password;
// Read username and pass from data file
ifstream dataFile("lab2.data");
dataFile >> user >> password; //hopefully this will parse white
dataFile.close();
// Get username and pass from user
string user1;
string password1;
cout << "Please enter your username" << endl;
getline (cin, user1);
cout << "Please enter your password" << "\n";
getline (cin, password1);
// Now we compare user/password with one from file
if ((user1 == user) && (password1 == password))
cout << "Success, you are signed in!" << endl;
else
cout << "Username and/or password incorrect. Try again." <<
"\n";
}
};
int main ()
{
PasswordSystem Shazam;
Shazam.login();
return 0;
}
|
So far, I know there are 2 parts that are required for the program to read the config file. config.h, a header file and finally, extracting the config code to run in main.
Now, the contents of my configuration file is something like this:
1 2 3 4
|
# This is the configuration file
# In the future, there may be other configuration keys and values
# For now, there is only the one which controls login attempts:
Attempts = 3
|
I've come across posts on cplusplus.com that shows me exactly how to do it ( I think)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
#include <iostream>
#include <map>
#include <string>
namespace configuration
{
//---------------------------------------------------------------------------
// The configuration::data is a simple map string (key, value) pairs.
// The file is stored as a simple listing of those pairs, one per line.
// The key is separated from the value by an equal sign '='.
// Commentary begins with the first non-space character on the line a hash or
// semi-colon ('#' or ';').
//
// Example:
// # This is an example
// source.directory = C:\Documents and Settings\Jennifer\My Documents\
// file.types = *.jpg;*.gif;*.png;*.pix;*.tif;*.bmp
//
// Notice that the configuration file format does not permit values to span
// more than one line, commentary at the end of a line, or [section]s.
//
struct data: std::map <std::string, std::string>
{
// Here is a little convenience method...
bool iskey( const std::string& s ) const
{
return count( s ) != 0;
}
};
//---------------------------------------------------------------------------
// The extraction operator reads configuration::data until EOF.
// Invalid data is ignored.
//
std::istream& operator >> ( std::istream& ins, data& d )
{
std::string s, key, value;
// For each (key, value) pair in the file
while (std::getline( ins, s ))
{
std::string::size_type begin = s.find_first_not_of( " \f\t\v" );
// Skip blank lines
if (begin == std::string::npos) continue;
// Skip commentary
if (std::string( "#;" ).find( s[ begin ] ) != std::string::npos) continue;
// Extract the key value
std::string::size_type end = s.find( '=', begin );
key = s.substr( begin, end - begin );
// (No leading or trailing whitespace allowed)
key.erase( key.find_last_not_of( " \f\t\v" ) + 1 );
// No blank keys allowed
if (key.empty()) continue;
// Extract the value (no leading or trailing whitespace allowed)
begin = s.find_first_not_of( " \f\n\r\t\v", end + 1 );
end = s.find_last_not_of( " \f\n\r\t\v" ) + 1;
value = s.substr( begin, end - begin );
// Insert the properly extracted (key, value) pair into the map
d[ key ] = value;
}
return ins;
}
//---------------------------------------------------------------------------
// The insertion operator writes all configuration::data to stream.
//
std::ostream& operator << ( std::ostream& outs, const data& d )
{
data::const_iterator iter;
for (iter = d.begin(); iter != d.end(); iter++)
outs << iter->first << " = " << iter->last << endl;
return outs;
}
} // namespace configuration
|
and step 2 being
1 2 3 4 5 6 7 8 9 10
|
#include "configuration.h";
int main()
{
configuration::data myconfigdata;
ifstream f( "myprog.ini" );
f >> myconfigdata;
f.close();
...
}
|
I'm not sure where to start writing exactly the code needed to read the value attempts and to do what you want it to do.
Remember to keep our code jargon and instructions down to what a beginner can understand, for as you can see, I'm quite new at this.
Thanks in advance!