My program (reward system that deals with customers/items) involves getting input from the user multiple times. The usual case is that the user has to either enter a number, or type in a string. I use the standard std::cin to handle any numbers the user inputs, and std::getline() for any string they enter. My problem is that when I include a space before / after inputting a string (such as a customer's name or an item's name) it doesn't read it properly. EX: inputting the item name 'water pipe' or customer name 'John' with no spaces before or after works, but something like 'water pipe ' or ' John' with a space afterwards/beforehand ends the program. Is there any way to have std::getline() ignore white spaces before/after the user inputs a string? I noticed this problem first in my addPoints() function so I will include that here, but this is happening in my other functions also. The contents of both of the files are structured the same, with item/customer name then their points beneath them. So like this:
lighter
10
water pipe
10
And so on. Here is the code:
std::cout << "Would you like to add points to an existing member? If not, input 0 to look at other options!" << std::endl;
std::cout<< "Otherwise, input 1 to continue to the point system." << std::endl;
std::cin >> answer;
std::cin.sync();
if (answer == '0')
options();
if (answer == '1') {
inFS.open("name.dat");
if (!inFS.is_open()){
std::cout << "Could not find name.dat." << std::endl;
exit(1);
}
while (std::getline(inFS, item)) {
std::getline(inFS, points);
nameList.push_back(make_pair(item, std::stoi(points)));
}
if (!inFS.eof())
std::cout << "Failure before reaching end of file." << std::endl;
inFS.close();
std::cout << "Please enter the username of the rewards member you would like to add points to." << std::endl;
std::getline(std::cin, userName);
std::cin.sync();
for (int i = 0; i < nameList.size(); i++) {
if (nameList[i].first == userName) {
validName = true;
break; //fix this later so it includes a 'sorry, invalid name' type of comment//
}
if (nameList[i].first != userName) {
validName = false;
continue;
}
}
if (validName == false)
nameList.clear();
if (validName == true) {
std::cout << "Which rewards product did " << userName << " purchase?" << std::endl;
std::getline(std::cin, product);
//find out why adding a space at the end of each input ends the program//
std::cin.sync();
inFS.open("items.dat");
if (!inFS.is_open()){
std::cout << "Could not find items.dat." << std::endl;
exit(1);
}
while (std::getline(inFS, item)) {
std::getline(inFS, points);
itemList.push_back(make_pair(item, std::stoi(points)));
}
if (!inFS.eof())
std::cout << "Failure before reaching end of file." << std::endl;
inFS.close();
I haven't read your program too closely, but std::getline always reads up to (and then subsequently discards) a newline character '\n'
. Instead, try trimming the strings after the call to std::getline
. Unfortunately, there's no built in functions for trimming whitespace, but the following functions work (copy-pasted from https://stackoverflow.com/a/217605/8421788 ):
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
// trim from start (in place)
static inline void ltrim(std::string &s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(),
std::not1(std::ptr_fun<int, int>(std::isspace))));
}
// trim from end (in place)
static inline void rtrim(std::string &s) {
s.erase(std::find_if(s.rbegin(), s.rend(),
std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
}
// trim from both ends (in place)
static inline void trim(std::string &s) {
ltrim(s);
rtrim(s);
}
Then, you can use them in the following way:
std::getline(std::cin, userName);
userName = trim(userName);
/* ... process user name as needed ... */
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.