I am just studying so don't judge me hard please.
I have a problem. I know how to do a do-while loop. But today I have learned about functions. So I made do-while loops in functions and they are looping infinitely. How do I stop the loops?
#include <iostream>
using namespace std;
void text()
{
cout << "Log in to see the Menu. " << endl;
}
void lg()
{
const string login = "el1oz";
string input;
cout << "Login > " << flush;
cin >> input;
do{
if(login == input){
break;
}
else{
cout << "Try again." << endl;
}
}while(true);
cout << "Correct Login! " << endl;
}
void pw()
{
const string password = "Mau01171995";
string input1;
cout << "Password > " << flush;
cin >> input1;
do{
if(password == input1){
break;
}
else{
cout << "Try again. " << endl;
}
}while(true);
cout << "Correct Passsword! " << endl;
}
int main()
{
text();
lg();
pw();
return 0;
}
You're not changing input after the code enters in the loop. You should put the cin >> input inside the loop.
Also consider when to use a while loop vs a do while loop. In this case a while loop is better.
You probably should not use using namespace std; (More information here).
You should use more descriptive names.
#include <iostream>
using std::cin;
using std::string;
using std::cout;
using std::flush;
using std::endl;
void printWelcome()
{
cout << "Log in to see the Menu. " << endl;
}
void inputUser()
{
const string login = "el1oz";
string input;
cout << "Login > " << flush;
while(cin >> input){
if(login == input){
break;
}
else{
cout << "Try again." << endl;
}
}
cout << "Correct Login! " << endl;
}
void inputPassword()
{
const string password = "Mau01171995";
string input;
cout << "Password > " << flush;
while(cin >> input){
if(password == input){
break;
}
else{
cout << "Try again. " << endl;
}
}
cout << "Correct Passsword! " << endl;
}
int main()
{
printWelcome();
inputUser();
inputPpassword();
return 0;
}
Related
I've been attempting this for awhile but I keep getting lost the more I look into it.
I've been attempting to create a system which allows a user to input their sign up details, have them stored in a file, then later have a login which validates that file.
So far, I've come up with some code, but it's like it's only reading the start of the file and only validating that. I know it shouldn't work, but I don't know how to go about fixing it.
#include <iostream>
#include <string>
#include <fstream>
#include <string.h>
using namespace std;
class file {
private:
string Name, password;
string ID;
public:
void Display();
int Menu();
void addtofile();
void VerifyPass();
};
int main()
{
file Obj;
Obj.Menu();
Obj.Display();
Obj.addtofile();
Obj.VerifyPass();
}
int file::Menu() // The
{
int Option = 0;
attemp:
system("cls");
cout << "1: Sign u " << endl;
cout << "2: Login: " << endl;
cout << "3: Exit" << endl;
cout << "Select Option: " << endl;
cin >> Option;
switch(Option)
{
case 1:
addtofile();
break;
case 2:
VerifyPass();
break;
case 3:
exit(0);
break;
default:
cout << "Wrong Input, attempt again";
goto attemp;
}
return 0;
}
void file::addtofile() // Sign up pag:
{
// system("cls");
ofstream File("Test.txt");
cout << "Sign Up: \n \n \n";
cout << "Enter Name: ";
cin >> Name;
File << Name << endl;
cout << "Enter Password: ";
cin >> password;
File << password << endl;
cout << "Enter ID: ";
cin >> ID;
File << ID << "\n";
File.close();
// cout << "Finished" << endl;
// system("cls"); //
Menu();
}
void file::VerifyPass() // For verifying the user has inputted the correct information
{
string line1;
string PasswordInput2;
string NameInput2;
string IDInput2;
bool IsNamevalid = false;
bool IsIDvalid = false;
bool IsPassvalid = true;
do {
ifstream input("Test.txt", ios::app); // Iosapp is from my understanding, a pointer which allows the program to navigate a file.
system("cls");
cout << "Login: \n";
cout << "Enter Name: " << endl;
cin >> NameInput2;
cout << "Enter Password: " << endl;
cin >> PasswordInput2;
cout << "Enter ID: " << endl;
cin >> IDInput2;
while (!input.eof())
{ // eof is end of file
getline(input, line1);
if (NameInput2 == line1)
{
IsNamevalid = true;
}
if (PasswordInput2 == line1)
{
IsNamevalid = true;
}
if (IDInput2 == line1)
{
IsIDvalid = true;
}
input.close();
}
if (IsNamevalid == false)
{
cout << "Wrong Name , please attempt again" << endl;
input.close();
system("pause");
}
if (IsPassvalid == false)
{
cout << "Wrong Password, Please attempt again" << endl;
input.close();
system("pause");
}
if (IsIDvalid == false)
{
cout << "Invalid ID, please attempt again" << endl;
system("pause");
}
else
{
"Login Successful";
}
} while (IsNamevalid, IsPassvalid, IsIDvalid == false);
system("pause");
}
void file::Display() // just displays what the user inputted for the sign up page
{
system("cls");
string text;
ifstream Readfile("Test.txt");
while (getline(Readfile, text))
{
cout << text << endl;
}
Readfile.close();
cout << "Click to continue to Menu" << endl;
system("pause");
Menu();
}
There are a lot of problems with your code.
main() should not be calling addtofile() and VerifyPass() since those are called inside of Menu().
Menu() should use a do..while loop instead of goto.
VerifyPass() using !eof() in a loop is wrong (Display() loops correctly).
addtofile() is not specifying any flags when opening the file, so it wipes out the existing data. You need to specify the ios::app flag to preserve any existing data. Using ios::app on an ifstream, as you are currently doing in VerifyPass(), is wrong. ios::app is an output-only flag, so it should be used on the ofstream in addtofile() instead.
addtofile() adds 3 new lines to the file per entry, but VerifyPass() only reads in and validates 1 line at a time. You need to read in 3 lines at a time and validate them together as a whole.
With that said, try something more like this instead:
#include <iostream>
#include <string>
#include <fstream>
#include <limits>
#include <cstdlib>
using namespace std;
class file {
public:
void Display();
void Menu();
void AddToFile();
void VerifyPass();
};
int main()
{
file Obj;
do
{
Obj.Menu();
Obj.Display();
}
while (true);
}
void file::Menu()
{
int Option = 0;
system("cls");
do
{
cout << "1: Sign u " << endl;
cout << "2: Login: " << endl;
cout << "3: Exit" << endl;
cout << "Select Option: " << endl;
cin >> Option;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
switch (Option)
{
case 1:
AddToFile();
return;
case 2:
VerifyPass();
return;
case 3:
exit(0);
return;
default:
cout << "Wrong Input, try again" << endl;
break;
}
}
while (true);
}
void file::AddToFile()
{
ofstream File("Test.txt", ios::ate);
if (!File.is_open())
{
cout << "Can't open/create file" << endl;
system("pause");
return;
}
string Name, Password, ID;
cout << "Sign Up: \n \n \n";
cout << "Enter Name: ";
getline(cin, Name);
File << Name << '\n';
cout << "Enter Password: ";
getline(cin, Password);
File << Password << '\n';
cout << "Enter ID: ";
getline(cin, ID);
File << ID << '\n';
File.close();
cout << "Finished" << endl;
system("pause");
}
void file::VerifyPass()
{
string line1, line2, line3;
string PasswordInput;
string NameInput;
string IDInput;
bool IsNamevalid = false;
bool IsIDvalid = false;
bool IsPassvalid = false;
ifstream input("Test.txt");
if (!input.is_open())
{
cout << "Can't open file" << endl;
system("pause");
return;
}
system("cls");
cout << "Login: \n";
cout << "Enter Name: " << endl;
getline(cin, NameInput);
cout << "Enter Password: " << endl;
getline(cin, PasswordInput);
cout << "Enter ID: " << endl;
getline(cin, IDInput);
while (getline(input, line1) &&
getline(input, line2) &&
getline(input, line3))
{
if (NameInput == line1)
{
IsNamevalid = true;
if (PasswordInput == line2)
{
IsPassvalid = true;
if (IDInput == line3)
{
IsIDvalid = true;
break;
}
}
}
}
input.close();
if (!IsNamevalid)
{
cout << "Wrong Name, please try again" << endl;
}
else if (!IsPassvalid)
{
cout << "Wrong Password, please try again" << endl;
}
else if (!IsIDvalid)
{
cout << "Invalid ID, please try again" << endl;
}
else
{
cout << "Login Successful";
}
system("pause");
}
void file::Display()
{
system("cls");
string text;
ifstream Readfile("Test.txt");
while (getline(Readfile, text)) {
cout << text << endl;
}
Readfile.close();
system("pause");
}
#include <iostream>
using namespace std;
bool play_game(int n) {
int guess;
bool noguesses = false;
int numofguesses = 0;
cout << "Welcome to my number guessing game\n";
while (n!=guess && !noguesses)
{
if (numofguesses < 6)
{
cout << "\n";
cout << "Enter your guess: ";
cin >> guess;
cout << "\n";
cout << "You entered: " << guess;
numofguesses++;
return false;
}
else
{
oog = true;
}
}
if (noguesses) {
cout << "I'm sorry. You didn't find my number.\n";
cout << "It was" << n << endl;
}
else
{
cout << "\n";
cout << "You found it in" << numofguesses << "guess(es)\n";
return true;
}
}
int main()
{
int secretnum = 5;
play_game(secretnum);
}
When I run this, the program stops after cout << "You entered: " << guess;. I want it to keep looping until the number of guesses reaches 6, or until the user inputs the correct answer.
Remove return false;
if (numofguesses < 6)
{
cout << "\n";
cout << "Enter your guess: ";
cin >> guess;
cout << "\n";
cout << "You entered: " << guess;
numofguesses++;
return false; //Remove this line
}
In the adding user section in the code below, I am unable to type any characters for the "Add another person?(y/n): " question. it just jumps back to entering age. How do I fix this?
I've tried to change ans into a string, implement a while loop to force the question to show up, and many other things. It just seems that nothing works and I've been trying it for the good part of two hours
#include <iostream>
#include <string>
#include <Windows.h>
using namespace std;
int main()
{
char ans;
int people;
int option;
int count = 0;
struct data
{
string name;
int age;
char gender;
string comments;
}person[100];
// homescreen
homescreen:
cout << "Welcome to the Data Base!" << endl;
cout << endl;
// displaying all people
for (int list = 0; list < count; list++)
{
cout << list << ".) " << person[list].name << endl;
}
cout << endl;
cout << "[1] View Person" << endl;
cout << "[2] Add Person" << endl;
cout << "[3] Edit Person" << endl;
cout << "[4] Delete Person" << endl;
cout << "[5] Exit" << endl;
cout << "Choose Option: "; cin >> option;
// using options
while (option != 5)
{
if (option == 1)
{
view:
for (int list2 = 0; list2 < count; list2++)
{
cout << list2 << ".) " << person[list2].name << endl;
}
cout << endl;
cout << "Enter number of person you want: "; cin >> people;
system("cls");
cout << "Name: " << person[count].name << endl;
cout << "Age: " << person[count].age << endl;
cout << "Gender: " << person[count].gender << endl;
cout << "Comments: " << person[count].comments << endl << endl;
cout << "View another person?(y/n): "; cin >> ans;
if (ans == 'y')
{
system("cls"); goto view;
}
else if (ans == 'n')
{
system("cls"); goto homescreen;
}
}
if (option == 2)
{
add:
system("cls");
cout << "Name: "; cin >> person[count].name;
system("cls");
cout << "Age: "; cin >> person[count].age;
system("cls");
cout << "Gender(M/F/H): "; cin >> person[count].gender;
system("cls");
cout << "Comments: "; cin >> person[count].comments;
count++;
system("cls");
cout << "Add another person?(y/n): "; cin >> ans;
if (ans == 'y')
{
system("cls");
goto add;
}
else if (ans == 'n')
{
system("cls");
goto homescreen;
}
}
}
}
If you anybody can help me I'd be grateful
The goto statements in your code makes the program really good
spaghetti
structure and that is not
good.
Therefore, think instead of goto other options, such as infinite
while loop which will break once the user enters the n or moving
the code to the function.
Secondly what if you have not entered any persons and choosing the
option 1. You still output the attributes of the person as
count is initialized zero at least. Remember the attributes are
not initialized at this point. Accessing the uninitialized
variables will invoke undefined
behavior. Therefore,
provide a check (something like if(count > 0) )before you execute the code in option 1.
In addition to that, remember that
std::endl flushes the output buffer, and '\n' doesn't. Therefore, most of
the cases you might wanna use just
\n.
Last but not the least, use std::vector instead of the using C style arrays with some predefined size. What if the user has more than 100 inputs? The solution in C++ is std::vector, which can expand dynamically as its storage is handled automatically.
Following is a possible solution to your program, in which the comments will guide you through to the things that I mentioned above.
#include <iostream>
#include <string>
#include <vector>
#include <windows.h>
struct Data
{
std::string name;
int age;
char gender;
std::string comments;
Data(const std::string& n, int a, char g, const std::string& c) // provide a Constructor
:name(n), age(a), gender(g), comments(c)
{}
};
void debugMsg(const std::string& msg)
{
system("cls");
std::cout << "\n\n\t\t" << msg << "\n\n";
Sleep(3000);
}
int main()
{
std::vector<Data> person; // use std::vector to store the datas
while (true) // loop: 1
{
system("cls");
std::cout << "Welcome to the Data Base! \n\n";
std::cout << "[1] View Person\n";
std::cout << "[2] Add Person\n";
std::cout << "[3] Edit Person\n";
std::cout << "[4] Delete Person\n";
std::cout << "[5] Exit\n";
std::cout << "Choose Option: ";
int option; std::cin >> option;
switch (option) // use switch to validate the options
{
case 1:
{
while (true) // loop - 2 -> case 1
{
// if no data available to show -> just break the loop 2 and return to the outer loop(i.e, loop 1)
if (person.empty()) { debugMsg("No person available to show ....going to main manu...."); break; }
// otherwise: displaying all people
for (std::size_t index = 0; index < person.size(); ++index)
std::cout << index << ".) " << person[index].name << "\n";
std::cout << "\nEnter number of person you want: ";
std::size_t index; std::cin >> index;
// if the index is not valid -> just break the loop 2 and return to the outer loop(i.e, loop 1)
if (index < 0 || index >= person.size()) { debugMsg("Sorry, wrong index!... returning to the main menu......"); break; }
system("cls");
std::cout << "Name: " << person[index].name << std::endl;
std::cout << "Age: " << person[index].age << std::endl;
std::cout << "Gender: " << person[index].gender << std::endl;
std::cout << "Comments: " << person[index].comments << std::endl << std::endl;
std::cout << "View another person?(y/n): ";
char ans; std::cin >> ans;
if (ans == 'y') { system("cls"); continue; } // just continue looping
else if (ans == 'n') { break; } // this will break the loop 2 and return to the outer loop(i.e, loop 1)
else { debugMsg("Sorry, wrong option!... returning to the main menu......"); break; }
}
} break;
case 2:
{
while (true) // loop - 3 -> case 2
{
system("cls");
std::string name, comments; int age; char gender;
std::cout << "Name: "; std::cin >> name;
std::cout << "Age: "; std::cin >> age;
std::cout << "Gender(M/F/H): "; std::cin >> gender;
std::cout << "Comments: "; std::cin >> comments;
// simply construct the Data in person vector in place
person.emplace_back(name, age, gender, comments);
std::cout << "\n\nAdd another person?(y/n): ";
char ans; std::cin >> ans;
if (ans == 'y') { system("cls"); continue; }
else if (ans == 'n') { system("cls"); break; } // same as case 1
else { debugMsg("Sorry, wrong option!... returning to the main menu......"); break; }
}
} break;
case 3: { /*code*/ debugMsg("Sorry, Not implemented!... returning to the main menu......"); } break;
case 4: { /*code*/ debugMsg("Sorry, Not implemented!... returning to the main menu......"); } break;
case 5: return 0; // if its 5, just retun the main
default: break;
}
}
return 0;
}
As mentioned above, using "goto" is a bad style, so i would suggest structure your program a little. Below is my version.
Naturally, I did not add any checks and controls, the author will be able to do this on his own. But main logics should work. And, of course, it is better to use vector instead of static array.
#include <iostream>
#include <string>
#include <Windows.h>
using namespace std;
enum options { OPT_VIEW = 1, OPT_ADD = 2, OPT_EDIT = 3, OPT_DELETE = 4, OPT_EXIT = 5 };
struct data
{
string name;
int age;
char gender;
string comments;
};
class App
{
private:
data person[100];
int count = 0;
public:
App();
void Run();
int HomeScreen();
void View();
void Add();
};
App::App() : count(0)
{}
void App::Run()
{
int option = HomeScreen();
while(option != OPT_EXIT)
{
switch(option)
{
case OPT_VIEW:
View();
break;
case OPT_ADD:
Add();
break;
}
option = HomeScreen();
}
}
int App::HomeScreen()
{
int option = 0;
cout << "Welcome to the Data Base!" << endl;
cout << endl;
// displaying all people
for(int list = 0; list < count; list++)
{
cout << list << ".) " << person[list].name << endl;
}
cout << endl;
cout << "[1] View Person" << endl;
cout << "[2] Add Person" << endl;
cout << "[3] Edit Person" << endl;
cout << "[4] Delete Person" << endl;
cout << "[5] Exit" << endl;
cout << "Choose Option: "; cin >> option;
return option;
}
void App::View()
{
char ans = 0;
do
{
int people = 0;
for(int list2 = 0; list2 < count; list2++)
{
cout << list2 << ".) " << person[list2].name << endl;
}
cout << endl;
cout << "Enter number of person you want: "; cin >> people;
system("cls");
cout << "Name: " << person[people].name << endl;
cout << "Age: " << person[people].age << endl;
cout << "Gender: " << person[people].gender << endl;
cout << "Comments: " << person[people].comments << endl << endl;
cout << "View another person?(y/n): "; cin >> ans;
}
while(ans == 'y');
system("cls");
}
void App::Add()
{
char ans = 0;
do
{
system("cls");
cout << "Name: "; cin >> person[count].name;
system("cls");
cout << "Age: "; cin >> person[count].age;
system("cls");
cout << "Gender(M/F/H): "; cin >> person[count].gender;
system("cls");
cout << "Comments: "; cin >> person[count].comments;
count++;
system("cls");
cout << "Add another person?(y/n): "; cin >> ans;
}
while(ans == 'y');
system("cls");
}
int main()
{
App program;
program.Run();
}
Not under standing looping for arrays. Looping through all of grab some or search. Can someone explain the process? Thanks in advance. Sorry if duplicate. I looked around and couldnt find a solid explaination that I could understand.
#include <fstream>
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
void allContacts(string names[], string phones[])
{
cout << "Showing all contacts... Press Q to go back to main menu" << endl;
}
void addName(string names[], string phones[])
{
bool keepGoing;
string input;
beginning:
for (int i = 0; i < sizeof(names); i++)
{
cout << "Enter contact name: ";
cin >> names[i];
cout << "Enter contact number: ";
cin >> phones[i];
cout << "Do you have another contact to add? y or no" << endl;
cin >> input;
if(input == "y" || input == "Y")
{
goto beginning;
}
if(input == "n" || input == "N")
{
cout << "Contacts you have entered: " << endl;
cout << names[i] << " : " << phones[i] << endl;
}
}
}
void searchName(string names[], string phones[])
{
string name;
cout << "Enter Name: ";
cin >> name;
cout << "Search for a name or Press Q to go back to main menu" << endl;
for (int i = 0; i < sizeof(names); i++){
if (name == names[i])
{
cout << counter << names[i] << " 's phone number is: " << phones[i] << endl;
} else {
cout << "No results found";
}
}
}
int main()
{
string names[100];
string phones[100];
int choice;
cout << "============================" << endl;
cout << "=== Welcome to PhoneBook ===" << endl;
cout << "============================" << endl;
cout << "1- Add a New Contact" << endl;
cout << "2- Search By Name" << endl;
cout << "3- Display All" << endl;
cout << "0- Exit" << endl;
cout << "Select a number: " << endl;
cin >> choice;
switch(choice)
{
case 1:
addName(names, phones);
break;
case 2:
searchName(names, phones);
break;
case 3:
allContacts(names, phones);
break;
case 0:
cout << "Exiting PhoneBook...";
break;
}
}
In C++ arrays lose attributes when passed to functions. Those attributes are capacity and size (number of filled slots). You will need to pass this additional information for each array:
void addName(string names[], unsigned int names_capacity, unsigned int names_size,
string phones[], unsigned int phones_capacity, unsigned int phones_size)
To get around this, you can use std::vector. The std::vector knows its capacity and size, so you don't have to pass additional attributes to your function.
Also, if you use tolower or toupper before you compare, you only need to make one comparison:
char input;
cout << "Do you have another contact to add? y or n" << endl;
cin >> input;
input = toupper(input);
if(input == 'Y')
When using strings, you can convert them to all uppercase or all lowercase by using std::transform, such as:
std::transform(input.begin(),
input.begin(), input.end(),
tolower);
The part of code where I rename the file just won't work. I tried writing it separately in another project, it works. Help me please.
#include <iostream>
#include <stdio.h>
#include <fstream>
using namespace std;
int main () {
char address[] = "";
char newname[] = "";
int action;
char confirm;
int result;
cout << "File Manipulator 1.0" << endl;
cout << "--------------------" << endl << endl;
cout << "Type the full address of a file you wish to manipulate." << endl << endl;
ADDRESS:cin >> address;
fstream file(address);
if (!file.good()) {
cout << "The selected file does not exist! Try again. ";
goto ADDRESS;
} else {
cout << endl << "-----------------------------------" << endl;
cout << "Type 1 to move the selected file." << endl;
cout << "Type 2 to rename the selected file." << endl;
cout << "Type 3 to delete the selected file." << endl;
cout << "-----------------------------------" << endl << endl;
ACTION:cin >> action;
if (action == 1) {
cout << 1;
} else if (action == 2) {
cout << "Enter the new name: ";
cin >> newname;
cout << "Are you sure you want to rename the selected file? Y/N ";
CONFIRM:cin >> confirm;
if (confirm == 'Y' || 'y') {
result = rename(address, newname);
if (result == 0) {
cout << "renamed";
} else {
perror("not renamed");
}
} else if (confirm == 'N' || 'n') {
cout << "No";
} else {
cout << "You typed an invalid command! Try again. ";
goto CONFIRM;
}
} else if (action == 3) {
cout << 3;
} else {
cout << "You typed an invalid command! Try again." << endl;
goto ACTION;
}
}
return 0;
}
BTW the whole code is not finished, so check just the renaming part. Thanks.
Well, this is the solution.
#include <iostream>
#include <cstdio>
#include <fstream>
#include <string>
using namespace std;
int main() {
string address;
string newname;
Here you can see I used strings instead of char arrays.
char input;
int action;
char confirm;
int result;
cout << "File Manipulator 1.0" << endl;
cout << "--------------------" << endl << endl;
cout << "Type the full address of a file you wish to manipulate." << endl << endl;
getline(cin, address);
ifstream myfile(address.c_str());
I used ifstream with c_str() function which passes contents of a std::string into a C style string.
// try to open the file
if (myfile.is_open())
{
When the condition is met, you must close the opened file in order to be able to manipulate/work with it later.
myfile.close();
CREATE:cout << endl << "-----------------------------------" << endl;
cout << "Type 1 to move the selected file." << endl;
cout << "Type 2 to rename the selected file." << endl;
cout << "Type 3 to delete the selected file." << endl;
cout << "-----------------------------------" << endl << endl;
cin >> action;
switch (action)
{
case 1:
{
// do nothing.
}
break;
case 2:
{
// rename file.
cout << "Enter the new name" << endl << endl;
cin.ignore();
I used here the ignore() function to ignores the amount of characters I specify when I call it.
getline(cin, newname);
cout << "Are you sure you want ot rename the selected file ? Y/N" << endl << endl;
cin >> confirm;
if (confirm == 'Y' || confirm == 'y')
{
Same case with c_str() that i explained earlier.
rename(address.c_str(), newname.c_str());
}
}
break;
case 3:
{
// delete file.
remove(address.c_str());
}
break;
default:
{
cout << "You typed an invalid command!" << endl;
}
break;
}
}
else
{
cout << "The selected file does not exist! Would you like to create it? ";
cin >> input;
If the file name you input doesn't exist, you are prompted to create a file with the specified name, then you are redirected with goto to the manipulation menu.
if (input == 'y' || input == 'Y')
{
// create the file.
ofstream output(address.c_str());
output.close();
cout << "File created";
goto CREATE;
}
}
return 0;
}
Thanks for trying anyway :)