How to accept empty input in C++ - c++

Accepting user empty input and passing default value from the constructor
I just start learning C++. Now I was trying creating a simple requestion header.
What I was expected is the "ABC Industries" should be used as a default value for the purchaser name and "XYZ Supplier" should be used as a default for the vendor name.
I created a default constructor and a param constructor. Here is my code:
class Requisition{
private:
string purchaser, vendor;
public:
Requisition()
:purchaser("ABC Industries"),vendor("XYZ Supplier"){}
Requisition(string pname, string vname)
:purchaser(pname),vendor(vname){}
void getStaffInput(){
cout << "Enter a purchaser name: ";
cin>>purchaser;
cout << "Enter a vendor name: ";
cin>>vendor;
}
void printHeader(){
cout << "\n********************************************************\nPurchaser: "
<< purchaser <<"\nVendor: "<<vendor
<<"\n********************************************************"<<endl;
}
};
Here is my question:
How can I accept user inputting a empty string (user direct press enter or spacing) because in C++ will force to input something to continue.
If user doesn't key in any data, or just inputting either one of the data (purchaser or vendor), How can I pass the default value to the print function?
int main(){
Requisition req;
req.getStaffInput();
req.printHeader();
}
My program output is forcing the user to input something (can't be blank and spacing), the program should accepting those blank or spacing input and get the default value from the default constructor and display it.
Thanks.

cin into a string will read, effectively, one token. The exact rules are complicated, but it basically pulls content until a space or newline. If you don't input any content, it waits until there's something.
You're looking for getline, which reads until the next newline and returns whatever it finds, even if what it finds is nothing at all.
std::getline(std::cin, purchaser);

Related

How to detect a single Enter key in C++?

I am trying to get an input such as 'Country name'.
If you just press Enter, Country name should be set to default country name (ex)USA). Otherwise, input string would be set to country name. I am confused to how to detect input as a single Enter key or normal string.
Use std::getline() to read a whole line of user input up to the ENTER key (which will be read and discarded for you). If the returned string is empty, replace it with a default value as needed.
std::cout << "Country name: ";
std::countryName;
std::getline(std::cin, countryName);
if (countryName.empty())
countryName = "USA";
Try this
std::cout << "Country name: ";
std::getline(std::cin, countryName);
if(countryName==""){
countryName="USA"
}
also use
cin.ignore(); after every use of cin>> if you have to use getline() in the next line.
you can also use
cin.sync();
cin.get();

is there a way to read from a text file and store individual data as different variables?

I'm working on this program:
Create a program that will emulate an ATM machine. You must create a class named “ATM” that will have member functions that will:
Create a greeting on the screen,
Ask the user for a four digit pin,
a) an external file named “pin” must contain the following four pins and owner names and balances:
Larry 1234 $200
Moe 5678 $350
Lucy 0007 $600
Shirley 9876 $535
b) the pin input by the user must match one of the stored pins to allow access to transactions.
c) after 3 unsuccessful attempts, tell the user that their account is frozen and they must contact customer service.
After successful input of a pin, greet the user using their name.
Create a screen asking the user if they want to withdraw or deposit money or view their balance.
Initialize the beginning machine balance of $500. Track the balance based on deposits and withdraws.
Do not allow the user to withdraw more money than is currently in the machine.
Limit the amount of money withdrawn to $400.
The program must run on a continuous loop.
I cant figure out how to do 2b and 3. I think that I should create 4 different objects for the 4 different people, 1 line per object, then separate the name, pin, and balance within the object, but I'm not quite sure how to do that.
I think I should use something like getline() on a loop to separate the lines into the 4 objects then use fin >> name >> pin >> balance; to distinguish the name, pin, and balance, but I cant figure it out.
If I'm doing it all wrong then I would really appreciate a nudge in the right direction.
If you're reading in from an input stream, you can basically do it like this:
struct User {
std::string name;
int pin;
int amnt;
};
User read_user(std::istream& stream) {
User user;
// Reads in the username (this assumes the username doesn't contain a space)
stream >> user.name;
// Reads in the pin as an integer
stream >> user.pin;
stream.ignore(2); //Ignore the extra space and dollar sign
// Reads in the dollar amount as an integer
stream >> user.amnt;
// Returns the user
return user;
}
This will allow you to read from std::cin or from a filestream, and will return a user with the name, the pin, and the amount.
We can read in multiple users like this. Basically, we just call read multiple times.
std::vector<User> read_users(std::istream& stream, int n) {
std::vector<User> users;
for(int i = 0; i < n; i++) {
users.push_back(read_user(stream));
}
return users;
}
This will read in as many users as you'd like.
Reading in all the users in a file
We can also read in all the users in a file.
std::vector<User> read_all_users(std::istream& stream) {
std::vector<User> users;
while(true) // Checks that there's stuff left in the stream
{
User u = read_user(stream); // Try reading a user
if(not stream) break; // If there was nothing left to read, exit
users.push_back(u);
}
return users;
}
Example usage:
We're going to open a file called users.txt, and read all of them in. Then, we'll print out the name, pin, and account balance of each user.
int main() {
std::ifstream user_file("users.txt");
std::vector<User> users = read_all_users(user_file);
// This prints out the name, pin, and balance of each user
for(User& user : users) {
std::cout << "Name: " << user.name << '\n';
std::cout << "Pin: " << user.pin << '\n';
std::cout << "Amnt: " << user.amnt << '\n';
}
// Do stuff with the list of users
}

Detect a newline character with getline or istringstream

In my program, I'm asking the user for input via getline, and then in a separate class, splitting the string into three different strings which I will then check via a list of pre-determined values.
The way it works now, if someone enters an invalid command, I display "INVALID"
The problem I'm having is with a string containing only spaces or only a single newline character.
Here is what I'm trying to do:
std::string command; // command user enters
getline(std::cin, command); // user input here
std::string tempCheck; // if we have a value in here other than empty, invalid
// use istringstream to grab the words, max of 3
std::istringstream parse{fullCommand}; // parse command into words
if(fullCommand.empty()){ // nothing has been input
std::cout << "INVALID" << std::endl;
return;
}
parse >> command; // stores first word (the command)
parse >> actionOne; // stores second word as parameter
parse >> actionTwo; // stores third word as parameter
parse >> tempCheck;
if(!tempCheck.empty()) {
std::cout << "INVALID" << std::endl;
return;
}
The variable tempCheck basically means that if it goes over three words (the limit I want for commands), then it is INVALID. I also thought that having an empty string would work, but it just ends up in an infinite loop when nothing is input, but I just hit enter.
Here is what I expect my input to be doing (bold is output):
CREATE username password
**CREATED**
LOGIN username password
**SUCCEEDED**
ASDF lol lol
**INVALID**
**INVALID**
REMOVE username
**REMOVED**
**INVALID**
QUIT
**GOODBYE**
Here is what is happening:
CREATE username password
**CREATED**
// newline entered here
And it goes into a seemingly infinite loop. I can still type things, however, they don't actually affect anything. For example typing QUIT does nothing. But, if I restart my program and just type "QUIT" without trying to only use a newline character or only use a space, I get the expected output:
QUIT
**GOODBYE**
So, how do I tell either getline, or my istringstream, that if a user just enters a bunch of spaces and then hits enter, OR if the user just hits enter, display invalid and return? And is there anyway to do this with just getline or istringstream?
Alex, the following code may be helpful:
std::string strip(std::string const& s, std::string const& white=" \t\n")
{
std::string::size_type const first = s.find_first_not_of(white);
return (first == std::string::npos)
? std::string()
: s.substr(first, s.find_last_not_of(white)-first+1);
}
You may apply it before creating the istringstream:
std::istringstream parse{strip(fullCommand)};
The above code was borrowed and slightly modified from the old well-known technique.

How can I separate user inputted string and store it into an array

I was wondering if you could help me and figure this out without using something like strtok. This assignment is meant for me to build something that will accept input and direct the user to the right area. I want to get something like....
Help Copy
and it stores it as
array[1] = Help
array[2] = Copy.
I tried to do something like cin>>arr[1]; and cin>>arr[2] but at the same time what if the user enters copy then I am not sure how to do it cause if I put just one cin then what if the user puts help copy.
Basically I am not sure how to accept any size input and store anything they put in as elements in an array.
I would try something like cin.get or getline but they don't seem to really help me and my cin idea was not helpful at all.
This is what I have so far.
int main()
{
string user;
cout<<"Hello there, what is your desired username?"<<endl;
cin >> user;
system("cls");
cout<<"Hello, " << user << "! How are you doing?"<<endl<<endl;
cout<< user << ": ";
return 0;
}
You can do it like this:
Read the entire line using getline
Make an input string stream from that line
Read the content of that string stream into a vector<string>. It will grow automatically to accommodate as many inputs as the user enters
Examine the size of the resultant vector to see how many entries the end-user made
Here is how you can do it in code:
// Prepare the buffer for the line the user enters
string buf;
// This buffer will grow automatically to accommodate the entire line
getline(cin, buf);
// Make a string-based stream from the line entered by the user
istringstream iss(buf);
// Prepare a vector of strings to split the input
vector<string> vs;
// We could use a loop, but using an iterator is more idiomatic to C++
istream_iterator<string> iit(iss);
// back_inserter will add the items one by one to the vector vs
copy(iit, istream_iterator<string>(), back_inserter(vs));
Here is a demo on ideone.
std::vector<std::string> myInputs;
std::cout << "Enter parameters: ";
std::copy(std::istream_iterator<std::string>(std::cin), std::isteram_iterator<std::string>(), std::back_inserter(myInputs));
// do something with the values in myInputs
If the user presses Enter in between each input, this will go until they cease the input (Crtl-D on Windows). If you want them to put all the parameters on a single line, you can read the input into a single string and then split the string up by spaces (or whatever delimiter you wish to use).

Can I use enter as an input?

I am trying to allow the user to either enter a string or just hit enter, and in that case I would use a default string.
cout << "Where should I save the exam (default (./)exam.txt): " ;
cin >> exam_filename;
But right now you can enter a string and it works fine, but if you hit enter it just keeps waiting for the user to type something. Any suggestions??
Okay so when I do this:
string exam_filename;
getline(cin, exam_filename);
if (exam_filename.empty())
// set to default string
now it always sets the string to the default string. It never gives me a chance to enter anything it just moves on the next part of the program autmoatically.
You really want to read a line. Just do it:
string exam_filename;
getline(cin, exam_filename);
if (exam_filename.empty())
// set to default string