Hello kdrewes,
I have be working on and testing all morning while thinking about what is wrong.
A little revision of your code to start with:
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 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
#include <iostream>
#include <fstream>
#include <string> // <--- Added. Needed for "std::getline" and for output, (cout or File Stream).
#include <vector> // <--- Is there a point to this?
#include <map>
using namespace std; // <--- Best not to use.
int main(/*int argc, const char * argv[]*/) // <--- If you do not use them you do not need them.
{
map<string, string>Login
{
{"Bill","Oakland"},
{"Jay","Berkeley"},
{"Bob","Sacramento"} // <--- Comma not needed here.
};
ofstream outFile("password.txt"/*, ios::out*/); // <--- Changed.
if (!outFile) // <--- Added.
{
return std::cerr << "\n File \"password.txt\" did not open\n\n", 1;
}
//string output; // <--- Not used.
for (auto& it : Login)
{
outFile << it.first << ' ' << it.second << endl;
}
outFile.close();
string userName,
passWord,
information;
bool flag{};
bool done{}; // <--- Added;
bool valid{};
vector<string>Data; // <--- Not really needed.
ifstream inFile("password.txt"/*, ios::in*/);
if (!inFile) // <--- Added.
{
return std::cerr << "\n File \"password.txt\" did not open\n\n", 2;
}
do
{
cout << "Input Username: ";
getline(cin, userName);
cout << "\nInput Password: ";
getline(cin, passWord);
map<string, string>::iterator it{ Login.find(userName)};
if (it != Login.end())
{
std::cout << "\n User name found!\n";
}
else
{
std::cerr << "\n User name not found!\n";
}
while (inFile >> information)
{
string temporary;
for (auto& info : information) // <--- Why are you reading 1 character at a time?
{
temporary += info;
}
Data.push_back(temporary);
}
for (size_t i = 0; i < Dsta.size(); i++)
{
if ((Data[i].find(userName) != string::npos) && (it->first == userName))
{
flag = true;
break;
}
}
if (flag)
{
for (size_t i = 0; i < Data.size(); i++)
{
if (Data[i].find(passWord) != string::npos && (it->second == passWord))
{
valid = true;
break;
}
}
}
if (valid)
{
cout << "\nCongratulations, you have successfully\nlogged into you profile.\n\n";
done = true;
}
else
{
cout << "\nInvalid login, please re-enter: \n\n";
flag = false;
}
} while (!done);
inFile.close(); // <--- Not required as the dtor will close the file when the function looses scope.
return 0; // <--- Not required, but makes a good break point for testing.
}
|
From the top I add the header file "<string>" because you need this for "std::getline()" and also when send a "std::string" to output, either the screen or a file.
In line 9 you are creating storage space for variables that you do not use. Maybe you have some idea for using command line arguments in the future. If so you can uncomment it later otherwise the compiler will just see
int main()
.
Defining the map this way makes it much easier to read than with all that indenting. Also you do not need the (=) when using the uniform initializer, the {}s.
On line 18 the "o" in "ofstream" implies that the stream will be for output. What is commented out can be removed because it is redundant and I believe it is ignored by the compiler. The same is true for "ifstream".
The lines that follow is to check that there is problem with opening the stream. Both input and output streams should be checked especially the input stream.
Using the file stream names of "read" and "write" are misleading. When I first looked at the code I had a different idea of what you were trying to do.
Now that that is covered, and once the file is created, writing the "map" to a file should be done at the end of the program and reading the file to create the "map" should be at the beginning.
I added line 38 because it is a chance to have a little fun with the code. You will see this in line 116.
Lines 42 - 47 are updated, but you do not need this here because you already have a populated "map" to use.
Line 57 works, but I would not be using it this way.
Lines 59 - 66 I added to deal with a name being found or not. Even with that the rest of the code still works.
Lines 68 - 78. You are really over doing this here.
while (inFile >> information)
. The formatted input here will up to the first white space or new line it finds, so "information" ends up with "Bill" then you use a for loop to create a temporary string of what you already have just to add the temporary string to a vector that you do not need.
Lines 80 - 88 and again with lines 92 - 100 you are using the for loops to read the vector, but "it" already has the address in the "map" that it needs. Creating and checking the vector is not needed.
The last if/else works although I did add line 107.
When I rework you code to just what you need I put that in the next post.
Andy