@dhayden.
Not an exact duplicate. this one has the misuse of cin.ignore();
Hello navilgameboy,
Testing your program I found many problems.
In the "#include" statements:
"stdio.h" this is not a standard C++ header file, but a C header file. FYI the proper header file would be "cstdio". Anyhow this is covered through "iostream" which eventually includes "cstdio" along with "cmath" and others.
"conio.h" again this is not a standard C++ header file.
salem c once wrote:
> #include<conio.h>
Obsolete since 1990, when the world stopped using DOS as a primary operating system.
|
Also not everyone has this header file available as some of the IDEs and compilers no longer include this. In the end you use nothing from this header file in your program.
"math.h" should be"cmath", but like "conio.h" I see nothing in this program that would need this file.
This is the tricky one:
1 2
|
#include <Windows.h>
#include <limits>
| |
In "minwindefs.h" it defines max as: #define max(a,b) (((a) > (b)) ? (a) : (b)) but in "limits" the function is completely different. About two years ago I was told if you use "Windows.h" and "limits" in the same file you will need to use:
1 2 3
|
#include <Windows.h>
#undef max // <--- From the "Windows.h" definition.
#include <limits>
| |
Then when you use:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // <--- Requires header file <limits>.
there should not be any problem with "max".
For now I will just say this:
using namespace std; // <--- Best not to use.
This line:
char user_input_inchar[256];
would be better defined as a "std::string", but that is irrelevant as it is never used in the program.
Lines 14 - 18 are global variables that are better put in the functions that use them or passed to a function if needed. If a variable passed needs its changes back in the calling function then pass by reference.
As a global with file scope any function can change the value of the global variables and it can be difficult to find where a problem is.
In the function "StatrUp()":
You open "Myfile", should be (myFile) as a variable like this should start with a lower case letter, as an "fstream". The next line opens the stream as (in, out and append) and this is the start of the problem.
The following if statement will always be true because if the file name does not exist opening the stream for output will create the file name which makes the if statement true, so you could be reading an empty file and not realize it.
It would work better to only open the file for input, close it when you are done and then open the file for output and append when it is time.
This way you could write your code as:
1 2 3 4 5 6 7 8
|
fstream myFile; //OPEN FILE TO STORE USERNAMES
myFile.open("Usernames_and_passwords.txt", fstream::in);
if (!myFile)
{
std::cout << "\n File " << std::quoted("Usernames_and_passwords.txt") << " did not open" << std::endl;
/*return 1;*/ exit(1); // <--- Use exit if not in "main".
}
| |
"std::quoted()" comes from the header file "iomanip". I have found that
#include <iostream>
is best followed by
#include <iomanip>
. Just my opinion.
You may also need some kind of pause before the "exit(1)" to give you time to read the message.
If the stream does not open you need to leave the program and fix the problem before you continue with the rest of the program.
This will eliminate the need for your if statement that does not work. Also it is not the best form to put the code in an if or else block.
The while loop is OK for reading the file, but if the loop ends and you continue you need to close the input file before you open it for output.
The variable "newprofile" should be defined as a "char" not a "std::string" and the prompt needs to ask for "Y" or "N". By including the header file "cctype" you can use the functions "std::tolower()" or "std::toupper()" then your if statement would be:
if (std::tolower(newprofile) == 'y')
then you would not need all the ||s to check for every possible answer.
In the if statement you have:
1 2 3
|
cout << "new profile username: ";
cin >> makenewusername;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // <--- Requires header file <limits>.
| |
This is your last use of
std::cin >>
and where you need to follow it with the "ignore". Placing it before a "std::getline" can work, but you need to be careful how it is used.
Either you had a problem with the "max()" function in the above ignore or yo do not understand the ignore function. "ignore" takes two parameters the first is a number, usually a large number. The
std::numeric_limits<std::streamsize>::max()
returns the largest possible value for what you are using, i.e., operating system, IDE and compiler. I have also seen 1000 used quite often. The second parameter is the delimiter, usually the "\n", but could be anything else as you need it. When you use
cin.ignore();
you are using the default parameters of "1" and "\n".
The "ignore" will ignore the number of characters of the first parameter or the delimiter whichever comes first. So
cin.ignore();
will ignore one character and move on. There are a few occasions where this will work, but not every time.
The two lines:
1 2
|
myFile.clear();
myFile.seekg(0, ios::beg);
| |
Are pretty much pointless at this point. The "clear" resets the state bits so you can use the file stream again, but if you open the file for just input and close it when you are done before you open the file stream for output this code is irrelevant to the program. And since you never read the input file a second time resetting the file point to the beginning has no use.
Now for the "TalkToAi" function:
I have nor worked on this part fully yet, but this is what I can see for now.
The while condition is based on "true" and therefore it is an endless loop with no way out. Like the Energizer Bunny it just keeps going and going.
The "cout statement "write something: " is misleading. It makes me think I can write anything, but the if statement is looking for something else and I have no idea what based on the prompt.
The "ignore" statement before the "std::getline()" will work the first time through the while loop, but is becomes a problem if you do not enter the first if block. But if you follow the last "cin.ignore" in the other function it is not needed here.
Should you enter the first if block the last
std::cin >>
needs to be followed by the ignore statement.
Your prompt:
cout << "when were you born?\n" << "Born: ";
makes me feel that I should enter a full date when all you want is the year. This would work better:
cout << "When were you born?\n" << "Birth year: ";
it is a better idea of what you are expecting. If you want to use a whole date you can write the "cin" as:
std::cin >> month >> junk << day <<junk << year;
with "junk" defined as a "char".
I have not fully tested the rest of the if statement, but the line:
cin >> user_birth_month;
needs to be followed with:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // <--- Requires header file <limits>.
In the second if statement you have:
ShellExecute(0, 0, L"http://www.google.com", 0, 0, SW_SHOW);
. The "L" in front of the quoted string is not needed. With my IDE and compiler it produces an error. When I removed the "L" it worked fine.
Hope that helps
Andy