I'm in the process of making a program that asks for a user to input a 4 digit number and then have that number stored into an array. There are not to be repeated numbers, so I created a function that is to check if the user inputted duplicates. If they did, the function is supposed to return false, and if they did not the function returns true. My problem is that when I go to run the program, it will prompt the user to enter a 4 digit number, but then once they do, the program states that it is already in the system..
Here is the function:
bool isExist(int ssn, int record[], int number_of_records)
{
if (record[ssn] < max_ssn && record[ssn] > min_ssn)
{
for (int i = 0; i < number_of_records; i++)
{
for (int j = i; j < number_of_records; j++)
{
if (record[i] == record[j])
{
return true;
}
else
{
return false;
}
}
}
}
}
And here is how I call it in main:
while (isExist)
{
cout << "Already in the system. Please enter a different social security number:\t";
cin >> record[ssn];
if (isExist == false)
{
cout << "Enter another four digit social security number:\t";
cin >> record[ssn];
}
}
Can someone help?
In you while loop you look to be referring to a variable isExist which never gets set to true, you don't appear to be making a call to your method isExist and setting your local variable
Your code never calls the isExist function. Try using it like this:
while (isExist(record[ssn], records, num_records))
{
cout << "Already in the system. Please enter a different social security number:\t";
cin >> record[ssn];
if (isExist == false)
{
cout << "Enter another four digit social security number:\t";
cin >> record[ssn];
}
}
Related
I'm trying to only allow integer values into my program, so I've made the following function. The function is similar to other ones I've seen online, and mine seems to work just fine up until I add an ! in front of it to check if something is not an int.
Function to check if input is an integer:
bool isInteger(std::string s)
{
for (int i = 0; i < s.length(); i++)
{
if (isdigit(s[i]) == false)
{
return false;
}
return true;
}
}
Function being put to use:
int getLevel()
{
int level;
std::cout << "Level One\n";
std::cout << "Level Two\n";
std::cout << "Level Three\n";
std::cout << "Level Four\n";
std::cout << "Level Five\n";
std::cout << "Enter your level (1-5): ";
std::cin >> level;
while (!isInteger(std::to_string(level)) || level < 1 || level > 5)
{
std::cout << "Enter an integer value between 1-5 inclusive: ";
std::cin >> level;
}
clrscr();
return level;;
}
I believe the function works just fine until I put the ! in front of it. I am trying to only allow integer input into my program, and when I enter a double or string, the console becomes flooded with the message "Enter an integer value between 1-5 inclusive: " and doesn't give any time to enter an input. I am fairly new to c++ programming and could use some advice. Thank you!
std::cin >> level;
will try to read an integer and it will never read anything other than an integer. If this fails std::cin's failbit is set and further input operations (like std::cin >> level; inside the loop) are skipped.
You need to check if the reading succeeded and ignore the current input if not. Like this for example:
std::cout << "Enter your level (1-5): ";
while(!(std::cin >> level) || level < 1 || level > 5) {
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Enter an integer value between 1-5 inclusive: ";
}
As little semi-related hint: level will always be an integer. Converting it to a string will always be the string-representation of an integer, so isInteger(std::to_string(level)) will always be true, unless level is negative, because you don't check for the sign.
Also that return true; in isInteger must be outside the loop, else you only check the first character.
Thanks to all the replies and clarification, I've managed to come up with a solution of my own.
New isInteger function that now checks for everything that is needed including inputs like "0004" that a user suggested above:
bool errorCheck(std::string s)
{
int intLevel;
std::stringstream tempLvl(s);
tempLvl >> intLevel;
for (int i = 0; i < s.length(); i++)
{
if (isdigit(s[i]) == false || s[0] == '0' || intLevel < 1 || intLevel > 5)
{
return false;
}
}
return true;
}
The method in action:
std::cout << "Enter your level (1-5): ";
std::cin >> stringLevel;
while (!errorCheck(stringLevel))
{
std::cout << "Enter an integer value between 1-5 inclusive: ";
std::cin >> stringLevel;
}
std::stringstream lvl(stringLevel);
lvl >> level;
clrscr();
return level;
}
Please let me know if you spot any problems with the code or have any easier solutions. Thanks for all the help!
ok i am gonna tell u the fact that console input extracts the input from console so if u ever tried to do something like that
i.e read string in place of integer the cin is going to be in bad state you can check this fact by putting an if like this
if(!cin>>level) break;
and u will find it working actually stream takes input from the console and convert it to boolean value so u can always check it's state bad state return false else true...... ..
SO,finally the bug is in cin>>level...
I hope u understood.... also check out that return true statement..
i am gonna put u reference link for more answer on this bug...
user enters String instead of Int
Would you be able to give me some suggestions for how I could simplify my code?
#include <iostream>
#include<fstream>
#include<string>
using namespace std;
int main() {
string current_users[5];
string new_users[5], new_user;
ifstream read;
read.open("current.txt");
for (int index = 0; index < 5; index++) {
read >> current_users[index];
}
read.close();
cout << "Enter a username: ";
cin >> new_user;
char user_choice;
int index = 0, new_index = 0;
while (index <= 5) {
if (new_user == current_users[index]) {
cout << "That username already exists."
<< " Enter a different username: ";
cin >> new_user;
index = 0;
continue;
}
if (index < 5)
index++;
else {
new_users[new_index] = new_user;
cout << "\nWelcome " << new_user << endl;
new_index++;
if (new_index < 5) {
cout << "Would you like to register another user?:"
<<"'Y' for yes or 'N' for no";
cin >> user_choice;
}
if (user_choice == 'Y' || user_choice == 'y') {
cout << "\nEnter a new username: ";
cin >> new_user;
index = 0;
}
else
break;
}
}//end of while
system("pause");
return 0;
}
This program asks a user to enter a username and checks if that username already exists. If it exists, it prompts the user to use a different username, also checking if that username already exists. If the username is unique the program welcomes the new user and asks if the user wants to register another new user (weird, but I wanted to try it). If the user wants to add another user to the "website" per say then the program runs again, checking for redundancy. I limited this program to 5 possible usernames to check and add for ease of testing. There's no errors.
The code is just chunky. I came up with this problem. I'm not in school. Can't afford it and wasn't admitted to any school where I applied. Any suggestions for online schools that offer degrees in computer science?
Here are some suggestions:
Array of Structures not parallel arrays
Use a std::vector of structures and not parallel arrays:
struct Record
{
std::string new_user;
std::string current_user;
};
std::vector<Record> database;
Processors that use a data cache like to have their elements close together. Here, new_user[0] would be next to current_user[0] in the cache.
With your parallel arrays, new_users[0] is next to current_user[4]; so the processor has to go past 4 elements to get to the first new_users element.
Loop Unrolling
You could eliminate the for loop for reading in your values:
read >> current_users[0];
read >> current_users[1];
read >> current_users[2];
read >> current_users[3];
read >> current_users[4];
This eliminates the overhead associated with a for loop.
Convert to all Lower or all Upper case before comparing
You can reduce the number of comparisons by converting to uppercase or lowercase before comparing:
if (std::toupper(user_choice) == 'Y')
Most of what you have is good. I'd wrap everything into a function and use std::find from the standard library in order to find duplicates.
template<std::size_t N, std::size_t M>
void GetUsers( std::string (&new_users)[N], std::string const (¤t_users)[M] ) {
int idx = 0;
while (idx < 5) {
std::cout << "Enter a username: ";
std::string user; std::cin >> user;
if (std::find(current_users.begin(), current_users.end(), user) != current_users.end()) {
std::cout << "That username already exists.\n";
continue;
} else {
new_users[idx++] = user;
if (idx < 5) {
std::cout << "Would you like to register another user? [Y/n]: ";
if (std::tolower(std::cin.get()) == 'y') {
continue;
}
}
break;
}
}
}
My question is to record the user 5 inputs and matching them to the correct code. singleperson code is 1, couple code is 2 and family is 3. Hence the users input will only be these 3 numbers.At the end I must calculate the total of the total number of people by their category. I ran the code and got runtime error saying stack around variable "groups" is corrupted and always have only 5 singles while the couples and families are 0. Sorry, I just started school and I'm a bit blurry..
int singleperson=0;
int couple=0;
int family3=0;
int groups[]={0,0,0,0,0};
cout << "Enter group #1:";
cin >>groups[0];
cout << "Enter group #2:";
cin >>groups[1];
cout << "Enter group #3:";
cin >>groups[2];
cout << "Enter group #4:";
cin >>groups[3];
cout << "Enter group #5:";
cin >>groups[4];
for (int a=0; a<=4;a++)
{
if(groups[a]=1)
{
singleperson= singleperson + 1;
}
else if(groups[a]=2)
{
couple = couple +1;
}
else
{
family3= family3+1;
}
}
cout<<"Statistics"<<endl;
cout <<singleperson<<"Singles"<<endl;
cout<<couple<<"Couples"<<endl;
cout<<family3<<"Families"<<endl;
Because size of group is 4 and you are trying to insert into 5th place. And as pointed by #antonio-garrido to check equality we use == and = is used for assignment.
int groups[]={0,0,0,0,0};
for (int a=0 ; a <= 4; a++) {
if(groups[a] == 1) {
singleperson= singleperson + 1;
} else if(groups[a] == 2) {
couple = couple +1;
} else {
family3= family3+1;
}
}
My project is to make a bank account program where the user enters an account number and a password to do anything within the program. The account numbers and passwords used must be stored as C-strings (the string header file is not allowed). I believe that the problem I am having is with the strcmp function. Here is my function where the problem occurs.
void get_password(int num_accounts, char **acc_num, char **password)
{
char account[ACCOUNT_NUMBER];
char user_password[PASS_LENGTH];
std::cout << "\nEnter the account number: ";
// std::cin.getline(account, ACCOUNT_NUMBER);
std::cin >> account;
int i = 0;
do
{
if (strcmp(account, *(acc_num + i)) != 0)
{
i++;
}
else
break;
} while (i <= num_accounts);
if (i == num_accounts)
{
std::cout << "\nCould not find the account number you entered...\nExiting the program";
exit(1);// account number not found
}
std::cout << "\nEnter the password: ";
// std::cin.getline(user_password, PASS_LENGTH);
std::cin >> user_password;
if (strcmp(user_password, *(password + i)) != 0)
{
std::cout << "\nInvalid password...\nExiting the program";
exit(1);// incorrect password
}
else
{
std::cout << "\nAccount number: " << account
<< "\nPassword: " << user_password << "\n";
return;
}
}
acc_num and password are both arrays of C-strings. When I run/debug the program, it crashes at the first if statement. I guess my question is whether I'm using the strcmp function correctly or not, or if there is a problem with the pointers that I am using.
Your loop will run even when num_accounts is 0. Also, you're doing an out-of-bound array access by writing while (i <= num_accounts); instead of while (i < num_accounts);.
It would be better to write it like this:
while (i < num_accounts)
{
if (strcmp(account, *(acc_num + i)) == 0)
{
// match found!
break;
}
i++;
}
You're assuming there is at least one account, and you're also looping once too often. A safer way to write it would be as follows:
for (int i = 0; i < num_accounts && !strcmp(account, accnum[i]); i++)
;
or the corresponding while loop. A do/while is not appropriate here.
I'm making an app that requires the user to input a production order (7 digits long) like this:
int order = 0;
cout << "Insert the order number: ";
cin >> ordem;
How can I prevent the user from entering a letter? Like "I2345G789"?
Doing that, my app just enters an infinite loop. I was thinking to use a function like this:
bool isLetter(int a)
{
string s = to_string(a);
for (int i = 0; i < s.size()-1; i++)
{
if (isdigit(s[i]))
{
return false;
}
else
return true;
}
}
And then:
if (isLetter(order))
{
cout << "Insert only numbers \n";
}
But it doesn't work. Why? And how can I improve the code?
PS: I'm very new to programming, so, sorry for any beginner mistakes.
I guess you have a loop around your code in order to ask for the order number again in case it contains non-digits, for example:
while(...)
{
int order = 0;
cout << "Insert the order number: ";
cin >> order;
}
If you enter something that cannot be parsed into an integer, then the input stream will go into failure mode and that might be the reason why you end up in an infinite loop. In order to overcome your problem in a simple way, you could read a string instead:
string order;
while (true)
{
cout << "Insert the order number: ";
cin >> order;
if (isLetter(order))
cout << "Insert only numbers" << endl;
else
break;
}
The function isLetter() now takes a string and looks like this:
bool isLetter(string s)
{
// Return true if the given string contains at least one letter.
for (size_t i = 0; i < s.size(); i++)
if (!isdigit(s[i]))
return true;
// Return false if there are only digits in the given string.
return false;
}
Please note, that it should be i < s.size() and not i < s.size()-1. And maybe you should rename your function isLetter() to hasLetter(), because that would be a bit more correct.