Parsing comma-delimited numbers in C++ - c++

I have a quick question for everyone. I'm trying to write a simple code to extract numbers form user input and save them to an int array, but I'm having a hard time wrapping my mind around how to make it work. The code shown below works well for single-digit numbers, but not so much for numbers with more than 1 digit.
For instance, if user enters: 1,2,3,4,50,60 here is what I get:
Enter numbers (must be comma delimited): 1,2,3,4,50,60
My numbers are: 12345060
My parsed numbers are: 1
My parsed numbers are: 2
My parsed numbers are: 3
My parsed numbers are: 4
My parsed numbers are: 5
My parsed numbers are: 0
Question: how can I modify this simple piece of code to accurately capture numbers with more than 1 digit? Thanks in advance!!
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
using namespace std;
// set up some variables
int numbers[100];
int main() {
// Enter numbers (comma delimited). Ex: 1,2,3,4,50,60<return>
cout << endl << endl << "Enter numbers (must be comma delimited): ";
string nums_in;
getline(cin, nums_in);
nums_in.erase(remove(nums_in.begin(), nums_in.end(), ','), nums_in.end()); // remove the unwanted commas
cout << "My numbers are: " << nums_in << endl;
// convert each char into int
for (int o = 0; o < 6; o++) {
istringstream buf(nums_in.substr(o,1));
buf >> numbers[o];
cout << "My parsed numbers are: " << numbers[o] << endl;
}
cout << endl << endl;
cout << "Done." << endl;
return 0;
}

In your program, you first remove the "unwanted" commas in the input string and then run into the problem that you cannot distinguish the numbers in the input line any more. So it seems as if these commas are not unwanted after all. The solution is to parse the string step by step without removing the commas first, as you need them to split up the input string. Here is an example.
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <vector>
int main() {
// Enter numbers (comma delimited). Ex: 1,2,3,4,50,60<return>
std::cout << std::endl << std::endl << "Enter numbers (must be comma delimited): ";
std::string nums_in;
std::getline(std::cin, nums_in);
// Now parse
std::vector<int> data;
std::istringstream buf(nums_in);
while (!buf.eof()) {
int this_number;
buf >> this_number;
if (buf.bad()) {
std::cerr << "Number formatting error!\n";
return 1;
}
data.push_back(this_number);
char comma = 0;
buf >> comma;
if (!buf.eof()) {
if (buf.fail()) {
std::cerr << "Could not read comma.\n";
return 1;
}
if (comma!=',') {
std::cerr << "Found no comma but '" << comma << "' instead !\n";
return 1;
}
}
}
std::cout << "My numbers are:";
for (auto a : data) {
std::cout << " " << a;
}
std::cout << std::endl;
std::cout << "Done." << std::endl;
return 0;
}
Note that I did not use "using namespace std;" as it is considered to be bad style. Also, I used a C++11 feature for printing out the values and used a vector to store the numbers - in your code, typing in a line with 200 numbers would lead to a crash (or other bad behavior). Finally, the parsing error handling is not yet complete. Making it complete and correct is left as an exercise. An alternative to the istringstream-based approach would be to first split the line by the commas and then to read all numbers separately using istringstreams.
By the way, your question is so practical that it would have been better suited for the standard stackexchange site - the connection to computer science is quite weak.

To solve this kind of problems, you have to write a scanner. The scanner breaks input into tokens. Once you have the ability to break the input into tokens, you can check the order of tokens (see parsers).
In your case you have three tokens: number, comma and end. An example of valid input: number comma number end. Another example: end (empty input). An example of invalid input: number number end (there is no comma between numbers).
Below it is a possible solution to your problem. get_token reads a token from input and stores it in token and number globals. get_numbers reads tokens, checks the syntax and stores the numbers in numbers; the count of numbers is stored in count (also global variables).
#include <iostream>
#include <cctype>
enum { max_count = 100 };
int numbers[max_count];
int count;
enum token_type
{
token_unknwon,
token_end,
token_comma,
token_number
};
token_type token;
int number;
token_type get_token()
{
char c;
// get a character, but skip ws except newline
while ( std::cin.get( c ) && c != '\n' && std::isspace( c ) )
;
if ( ! std::cin || c == '\n' )
return token = token_end;
if ( c == ',' )
return token = token_comma;
if ( std::isdigit( c ) )
{
std::cin.unget();
std::cin >> number;
return token = token_number;
}
return token_unknwon;
}
enum error_type
{
error_ok,
error_number_expected,
error_too_many_numbers,
error_comma_expected
};
int get_numbers()
{
//
if ( get_token() == token_end )
return error_ok; // empty input
while ( true )
{
// number expected
if ( token != token_number )
return error_number_expected;
// store the number
if ( count >= max_count )
return error_too_many_numbers;
numbers[count++] = number;
// this might be the last number
if ( get_token() == token_end )
return error_ok;
// not the last number, comma expected
if ( token != token_comma )
return error_comma_expected;
// prepare next token
get_token();
}
}
int main()
{
//...
switch ( get_numbers() )
{
case error_ok: break;
case error_comma_expected: std::cout << "comma expected"; return -1;
case error_number_expected: std::cout << "number expected"; return -2;
case error_too_many_numbers: std::cout << "too many numbers"; return -3;
}
//
std::cout << count << " number(s): ";
for ( int i = 0; i < count; ++i )
std::cout << numbers[i] << ' ';
//...
return 0;
}

This task can be easily done using std::getline to read the entire line in a string and then parse that string using a std::istringstream to extract the individual numbers and skip the commas.
#include <iostream>
#include <sstream>
#include <vector>
using std::cout;
int main() {
// Enter numbers (comma delimited). Ex: 1,2,3,4,50,60<return>
cout << "\nEnter numbers (must be comma delimited): ";
int x;
std::vector<int> v;
std::string str_in;
// read the whole line then use a stringstream buffer to extract the numbers
std::getline(std::cin, str_in);
std::istringstream str_buf{str_in};
while ( str_buf >> x ) {
v.push_back(x);
// If the next char in input is a comma, extract it. std::ws discards whitespace
if ( ( str_buf >> std::ws).peek() == ',' )
str_buf.ignore();
}
cout << "\nMy parsed numbers are:\n";
for ( int i : v ) {
cout << i << '\n';
}
cout << "\nDone.\n";
return 0;
}

Hm... How about parsing the string without removing the commas? Read the string character for character, placing each character in a temp buffer until you hit a comma, then convert the temp buffer to an int and store it in the vector. Empty the temp buffer and repeat.
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
// set up some variables
vector<int> numbers(0);
int main() {
// Enter numbers (comma delimited). Ex: 1,2,3,4,50,60<return>
cout << endl << endl << "Enter numbers (must be comma delimited): ";
string nums_in;
getline(cin, nums_in);
cout << "My numbers are: " << nums_in << endl;
string s_tmp = "";
int i_tmp;
for(vector<int>::size_type i = 0, len = nums_in.size(); i < len; i++){
if( nums_in[i] == ',' ){
if(s_tmp.size() > 0){
i_tmp = std::stoi(s_tmp);
numbers.push_back(i_tmp);
}
s_tmp = "";
}
else if( i == len-1){
s_tmp += nums_in[i];
i_tmp = std::stoi(s_tmp);
numbers.push_back(i_tmp);
cout << "My parsed numbers are:" << i_tmp << endl;
}
else {
s_tmp += nums_in[i];
}
}
cout << endl << endl;
cout << "Done." << endl;
return 0;
}

Related

C++ Loop for String

I am struggling to create a loop for getting input from user. The input must push_back() each instance.
#include <iostream>
#include <array>
#include <cstring>
#include <vector>
#include <string>
#include <string.h>
using namespace std;
int main()
{
vector <string> bookQ = { "what","book","is","that","you","are","reading" };
for (int i = 0; i < bookQ.size(); i++) {
cout << bookQ[i] << ' ';
}
cout << endl;
string input;
int x = 0;
for (x != '1') { // require a loop to input string and end when user prompts
cout << "Enter 1 to stop" << endl; //
cin >> x; //
getline(cin, input); //
bookQ.push_back(input); //
} //
for (int i = 0; i < bookQ.size(); i++) {
cout << bookQ[i] << ' ';
}
cout << endl;
return 0;
}
Your for loop is missing the declaration and (iteration) expression parts:
for (declaration-or-expression; declaration-or-expression; expression)
so it should have looked like this:
for (;x != '1';) {
which is generally written as
while (x != '1') {
That would cause problems though since it would not stop directly when the user entered 1.
You are also comparing an int with a char ('1'), so in order to exit the loop, the user would have had to enter 49 (the ASCII value for 1), not 1.
You are also mixing formatted input (cin >> x) with unformatted input (getline). I suggest that you stick to one only.
Example:
while(cout << "Enter 1 to stop\n", getline(cin, input) && input != "1") {
bookQ.push_back(input);
}
Assuming you meant that input is a string, then you've made a few mistakes with types. First of all, you've used wrong type for variable x, you used int which is integer type, and the type string is required. Secondly, when comparing x with '1' you used single quotes, which define the type of variable as char, not string. To make 1 a string you should use double quotes, like so "1". Besides that, you have used for(condition), which is incorrect syntax. You should use while(condition). Also, when your loop iterates, the x variable is the input book name, and input variable is always an empty string, so I would suggest replace input with x everywhere. The working code is below.
P.S. I am not sure whether you want "1" to be in the final vector, so I haven't changed that
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main() {
vector<string> bookQ = {"what", "book", "is", "that", "you", "are", "reading"};
for (int i = 0; i < bookQ.size(); i++) {
cout << bookQ[i] << ' ';
}
cout << endl;
string input;
string x;
while (x != "1") {
cout << "Enter 1 to stop" << endl;
cin >> x;
bookQ.push_back(x);
}
for (int i = 0; i < bookQ.size(); i++) {
cout << bookQ[i] << ' ';
}
cout << endl;
return 0;
}
simply check if input is 1 everytime the user enters somthing, and when it does = 1, simply break loop.
string x;
while (true) { // require a loop to input string and end when user prompts
cout << "Enter 1 to stop" << endl;
cin >> x;
if (x == "1"){
break;
}
getline(cin, x);
bookQ.push_back(x);
}
}
First, your for syntax is wrong. You want a while loop instead, or in this case a do..while loop would make more sense. Also, you are pushing the user's input into the vector before validating what the input actually is.
Second, x is an integer, but '1' is a character whose ASCII value is number 49. Your loop will never end, because != will always be true. Since you want the user to enter number 1 to stop the loop, you need to drop the quotes:
Third, what is the point of pre-populating bookQ? Just declare the bookQ without any initial data, and then cout the entire question as a normal string. This way, after the user is done entering input, the vector will contain only the user's input and nothing else.
Try something more like this:
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
using namespace std;
int main()
{
vector <string> bookQ;
string input;
cout << "what book is that you are reading" << endl;
do {
cout << "Enter a book, or 1 to stop" << endl;
getline(cin >> ws, input);
if (input == "1") break;
bookQ.push_back(input);
}
while (true);
for (size_t i = 0; i < bookQ.size(); ++i) {
cout << bookQ[i] << ' ';
}
cout << endl;
return 0;
}

Code gets stuck in loop (but loop itself doesn't keep going). C++ string

I am currently self-studying C++ with Schaum's outline book (which covers mostly C contents, or so I've been told, but whatever) and I have encountered some trouble with problem 9.8.
You are supposed to count the number of appearances of every different word in a given c++ string, for which I assumed each word was separated from the next one by a white space, a newline or a dot or coma (followed in these two last cases by another white space).
My code is the following:
#include <iostream>
#include <string>
using namespace std;
int main()
{ string s;
cout << "Enter text (enter \"$\" to stop input):\n";
getline(cin,s,'$');
string s2 = s, word;
int ini = 0, last, count_word = 0;
int count_1 = 0, count_2 = 0, count_3 = 0;
cout << "\nThe words found in the text, with its frequencies, are the following:\n";
for (ini; ini < s.length(); )
{ // we look for the next word in the string (at the end of each iteration
// ini is incremented in a quantity previous_word.length()
last = ini;
cout << "1: " << ++count_1 << endl;
while(true)
{ if (s[last] == ' ') break;
if (s[last] == '\n') break;
if (s[last] == ',') break;
if (s[last] == '.') break;
if (last > s.length()-1 ) break;
++last;
cout << "2: " << ++count_2 << endl;
}
--last; // last gives the position within s of the last letter of the current word
// now me create the word itself
word = s.substr(ini,last-ini+1); //because last-ini is word.length()-1
int found = s2.find(word);
while( found != s2.length() ) // the loop goes at least once
++count_word;
s2.erase(0,found+word.length()); // we erase the part of s2 where we have already looked
found = s2.find(word);
cout << "3: " << ++count_3 << endl;
cout << "\t["<<word<<"]: " << count_word;
++last;
s2 = s;
s2.erase(0,ini + word.length()); // we do this so that in the next iteration we don't look for
// the new word where we know it won't be.
if (s[last] == ' ' || s[last] == '\n') ini = last + 1;
if (s[last] == ',' || s[last] == '.') ini = last + 2;
count_word = 0;
}
}
When I ran the program nothing was sshown on screen, so I figured out that one of the loops must had been stuck (that is why I defined the variables count_1,2 and 3, to know if this was so).
However, after correctly counting the number of iterations for the fist word to be found, nothing else is printed and all I see is the command prompt (I mean the tiny white bar) and I cannot even stop the program by using ctrl z.
This is a very complicated method for a very simple problem. You can just use a stringstream to extract each word seperated by a white space. You then just take the extracted word and increment the word counter using a std::map<std::string, int>.
My take on this:
#include <iostream>
#include <map>
#include <string>
#include <sstream>
int main() {
std::map<std::string, int> word_to_count;
std::string in;
std::getline(std::cin, in);
std::stringstream s(in);
std::string temp_word;
while (s >> temp_word) {
word_to_count[temp_word]++;
}
for (const auto& x : word_to_count) {
std::cout << x.first << ": " << x.second << std::endl;
}
return 0;
}
input
hello world hello world test
Output
hello: 2
test: 1
world: 2
Keep in mind this is just one of many possible solutions, so just take this as inspiration :).

c++ count words in array

I need to write a function that gets a string and count how many words there are in the string and how many letters. And then calculate the average of it.
A word in a string is a sequence of letters and numbers separated by one or more spaces.
First of all I have to check if the string is correct. The string must contain only lowercase letters, uppercase letters, and numbers only.
i didnt menage to count all sort of words correctly and also my function doesnt count the last letter.
#include <iostream>
using namespace std;
#include <string.h>
#define SIZE 50
float checkString(char string[]) {
float wordCounter = 0;
float letterCounter = 0;
bool isLegit = true;
int i = 0;
while (isLegit) {
if (((string[i] >= 48 && string[i] <= 57) ||
(string[i] >= 65 && string[i] <= 90) ||
(string[i] >= 97 && string[i] <= 122 ))) {
for (int j = 0; j <= strlen(string); j++) {
if ((string[j - 1] != ' ' && string[j] == ' ' &&
string[i + 1] != ' ')
|| j == (strlen(string) - 1)) {
wordCounter++;
}
else if (string[j] != ' ') {
letterCounter++;
cout << string[j];
}
}
cout << " The avareage is : " << (letterCounter /
wordCounter) << endl;
isLegit = false;
}
else {
return -1;
isLegit = false;
}
}
cout << "Number of words " << wordCounter << endl;
cout << "Number of letters " <<letterCounter << endl;
}
int main() {
char string[SIZE];
cout << "please enter a sentence " << endl;
cin.getline(string, SIZE);
checkString(string);
}
Instead of using char[] for strings, I suggest that you use std::string which can grow and shrink dynamically. It's one of the most common types to use in the standard C++ library. You can also make use of stringstreams which lets you put a string inside it and then you can extract the contents of the stringstream using >>, just like when reading from std::cin.
Example with comments in the code:
#include <iostream>
#include <sstream> // std::stringstream
#include <string> // std::string
// use std::string instead of a char[]
float checkString(const std::string& string) {
// put the string in a stringstream to extract word-by-word
std::istringstream is(string);
unsigned words = 0;
unsigned letters = 0;
std::string word;
// extract one word at a time from the stringstream:
while(is >> word) {
// erase invalid characters:
for(auto it = word.begin(); it != word.end();) {
// Don't use magic numbers. Put the character literals in the code so
// everyone can see what you mean
if((*it>='0' && *it<='9')||(*it>='A' && *it<='Z')||(*it>='a' && *it<='z')) {
// it was a valid char
++it;
} else {
// it was an invalid char, erase it
it = word.erase(it);
}
}
// if the word still has some characters in it, make it count:
if(word.size()) {
++words;
letters += word.size();
std::cout << '\'' << word << "'\n"; // for debugging
}
}
std::cout << "Number of words " << words << "\n";
std::cout << "Number of letters " << letters << "\n";
std::cout << "The average number of letters per word is "
<< static_cast<float>(letters) / words << '\n';
return 0.f; // not sure what you are supposed to return, but since the function
// signature says that you should return a float, you must return a float.
}
int main() {
checkString(" Hello !!! World, now let's see if it works. ");
}
I would like to add an additional answer. This answer is based on "more-modern" C++ and the usage of algorithms. You want to solve 3 tasks:
Check, if string is OK and matched to your expectations
Count the number of words in the given string
Count the number of letters
Calculate the ratio of words/letters
For all this you may use existings algorithms from the C++ standard library. In the attached example code, you will see a one-liner for each task.
The statements are somehow very simple, so that I will not explain much more. If there should be a question, I am happy to answer.
Please see here one possible example code:
#include <iostream>
#include <string>
#include <iterator>
#include <regex>
#include <algorithm>
#include <tuple>
#include <cctype>
std::regex re("\\w+");
std::tuple<bool, int, int, double> checkString(const std::string& str) {
// Check if string consists only of allowed values, spaces or alpha numerical
bool stringOK{ std::all_of(str.begin(), str.end(), [](const char c) { return std::isalnum(c) || std::isspace(c); }) };
// Count the number of words
int numberOfWords{ std::distance(std::sregex_token_iterator(str.begin(),str.end(), re, 1), {}) };
// Count the number of letters
int numberOfLetters{ std::count_if(str.begin(), str.end(), isalnum) };
// Return all calculated values
return std::make_tuple(stringOK, numberOfWords, numberOfLetters, static_cast<double>(numberOfWords)/ numberOfLetters);
}
int main() {
// Ask user to input string
std::cout << "Please enter a sentence:\n";
// Get string from user
if (std::string str{}; std::getline(std::cin, str)) {
// Analyze string
auto [stringOk, numberOfWords, numberOfLetters, ratio] = checkString(str);
// SHow result
std::cout << "\nString content check: " << (stringOk ? "OK" : "NOK") << "\nNumber of words: "
<< numberOfWords << "\nNumber of letters: " << numberOfLetters << "\nRatio: " << ratio << "\n";
}
return 0;
}
Of course there are many more other possible solutions. But, because of the simplicity of this solution, I showed this variant.

Validating user input. Is The input an integer? C++ [duplicate]

I was typing this and it asks the user to input two integers which will then become variables. From there it will carry out simple operations.
How do I get the computer to check if what is entered is an integer or not? And if not, ask the user to type an integer in. For example: if someone inputs "a" instead of 2, then it will tell them to reenter a number.
Thanks
#include <iostream>
using namespace std;
int main ()
{
int firstvariable;
int secondvariable;
float float1;
float float2;
cout << "Please enter two integers and then press Enter:" << endl;
cin >> firstvariable;
cin >> secondvariable;
cout << "Time for some simple mathematical operations:\n" << endl;
cout << "The sum:\n " << firstvariable << "+" << secondvariable
<<"="<< firstvariable + secondvariable << "\n " << endl;
}
You can check like this:
int x;
cin >> x;
if (cin.fail()) {
//Not an int.
}
Furthermore, you can continue to get input until you get an int via:
#include <iostream>
int main() {
int x;
std::cin >> x;
while(std::cin.fail()) {
std::cout << "Error" << std::endl;
std::cin.clear();
std::cin.ignore(256,'\n');
std::cin >> x;
}
std::cout << x << std::endl;
return 0;
}
EDIT: To address the comment below regarding input like 10abc, one could modify the loop to accept a string as an input. Then check the string for any character not a number and handle that situation accordingly. One needs not clear/ignore the input stream in that situation. Verifying the string is just numbers, convert the string back to an integer. I mean, this was just off the cuff. There might be a better way. This won't work if you're accepting floats/doubles (would have to add '.' in the search string).
#include <iostream>
#include <string>
int main() {
std::string theInput;
int inputAsInt;
std::getline(std::cin, theInput);
while(std::cin.fail() || std::cin.eof() || theInput.find_first_not_of("0123456789") != std::string::npos) {
std::cout << "Error" << std::endl;
if( theInput.find_first_not_of("0123456789") == std::string::npos) {
std::cin.clear();
std::cin.ignore(256,'\n');
}
std::getline(std::cin, theInput);
}
std::string::size_type st;
inputAsInt = std::stoi(theInput,&st);
std::cout << inputAsInt << std::endl;
return 0;
}
Heh, this is an old question that could use a better answer.
User input should be obtained as a string and then attempt-converted to the data type you desire. Conveniently, this also allows you to answer questions like “what type of data is my input?”
Here is a function I use a lot. Other options exist, such as in Boost, but the basic premise is the same: attempt to perform the string→type conversion and observe the success or failure:
template <typename T>
auto string_to( const std::string & s )
{
T value;
std::istringstream ss( s );
return ((ss >> value) and (ss >> std::ws).eof()) // attempt the conversion
? value // success
: std::optional<T> { }; // failure
}
Using the optional type is just one way. You could also throw an exception or return a default value on failure. Whatever works for your situation.
Here is an example of using it:
int n;
std::cout << "n? ";
{
std::string s;
getline( std::cin, s );
auto x = string_to <int> ( s );
if (!x) return complain();
n = *x;
}
std::cout << "Multiply that by seven to get " << (7 * n) << ".\n";
limitations and type identification
In order for this to work, of course, there must exist a method to unambiguously extract your data type from a stream. This is the natural order of things in C++ — that is, business as usual. So no surprises here.
The next caveat is that some types subsume others. For example, if you are trying to distinguish between int and double, check for int first, since anything that converts to an int is also a double.
There is a function in c called isdigit(). That will suit you just fine. Example:
int var1 = 'h';
int var2 = '2';
if( isdigit(var1) )
{
printf("var1 = |%c| is a digit\n", var1 );
}
else
{
printf("var1 = |%c| is not a digit\n", var1 );
}
if( isdigit(var2) )
{
printf("var2 = |%c| is a digit\n", var2 );
}
else
{
printf("var2 = |%c| is not a digit\n", var2 );
}
From here
If istream fails to insert, it will set the fail bit.
int i = 0;
std::cin >> i; // type a and press enter
if (std::cin.fail())
{
std::cout << "I failed, try again ..." << std::endl
std::cin.clear(); // reset the failed state
}
You can set this up in a do-while loop to get the correct type (int in this case) propertly inserted.
For more information: http://augustcouncil.com/~tgibson/tutorial/iotips.html#directly
You can use the variables name itself to check if a value is an integer.
for example:
#include <iostream>
using namespace std;
int main (){
int firstvariable;
int secondvariable;
float float1;
float float2;
cout << "Please enter two integers and then press Enter:" << endl;
cin >> firstvariable;
cin >> secondvariable;
if(firstvariable && secondvariable){
cout << "Time for some simple mathematical operations:\n" << endl;
cout << "The sum:\n " << firstvariable << "+" << secondvariable
<<"="<< firstvariable + secondvariable << "\n " << endl;
}else{
cout << "\n[ERROR\tINVALID INPUT]\n";
return 1;
}
return 0;
}
I prefer to use <limits> to check for an int until it is passed.
#include <iostream>
#include <limits> //std::numeric_limits
using std::cout, std::endl, std::cin;
int main() {
int num;
while(!(cin >> num)){ //check the Input format for integer the right way
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cout << "Invalid input. Reenter the number: ";
};
cout << "output= " << num << endl;
return 0;
}
Under C++11 and later, I have the found the std::stoi function very useful for this task. stoi throws an invalid_argument exception if conversion cannot be performed. This can be caught and handled as shown in the demo function 'getIntegerValue' below.
The stoi function has a second parameter 'idx' that indicates the position of the first character in the string after the number. We can use the value in idx to check against the string length and ascertain if there are any characters in the input other than the number. This helps eliminate input like 10abc or a decimal value.
The only case where this approach fails is when there is trailing white space after the number in the input, that is, the user enters a lot of spaces after inputting the number. To handle such a case, you could rtrim the input string as described in this post.
#include <iostream>
#include <string>
bool getIntegerValue(int &value);
int main(){
int value{};
bool valid{};
while(!valid){
std::cout << "Enter integer value: ";
valid = getIntegerValue(value);
if (!valid)
std::cout << "Invalid integer value! Please try again.\n" << std::endl;
}
std::cout << "You entered: " << value << std::endl;
return 0;
}
// Returns true if integer is read from standard input
bool getIntegerValue(int &value){
bool isInputValid{};
int valueFromString{};
size_t index{};
std::string userInput;
std::getline(std::cin, userInput);
try {
//stoi throws an invalid_argument exception if userInput cannot be
//converted to an integer.
valueFromString = std::stoi(userInput, &index);
//index being different than length of string implies additional
//characters in input that could not be converted to an integer.
//This is to handle inputs like 10str or decimal values like 10.12
if(index == userInput.length()) isInputValid = true;
}
catch (const std::invalid_argument &arg) {
; //you could show an invalid argument message here.
}
if (isInputValid) value = valueFromString;
return isInputValid;
}
You could use :
int a = 12;
if (a>0 || a<0){
cout << "Your text"<<endl;
}
I'm pretty sure it works.

How to make an integer vector ignore white space and add 2 to every element in C++ [duplicate]

This question already has answers here:
How do I iterate over the words of a string?
(84 answers)
Closed 8 years ago.
I have a weird problem, so my instructor told us to create a simple program using vectors that will first ask the user how many integers they want to enter, and after the numbers were entered via a space as a delimiter the output should add 2 to each vector element.
Ex -
How many numbers are you going to enter = 4 (Lets assume the user enters 4)
Enter the numbers = 11 45 71 24 (Lets assume the user entered these 4 numbers)
THE OUTPUT SHOULD BE THIS = 13 47 73 26 (with spaces added 2)
Since using vectors is a must, i know how to add add 2 with a normal integer vector output but when it comes with spaces i have no idea, so far the program i wrote will accept everything before the space into the vector and will add 2 to it.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector <int> userInput;
int input;
int number;
int num1;
cout << "How many numbers are you going to enter ? :";
cin >> number;
cout << "Enter the Numbers : " << endl;
cin >> input;
userInput.push_back(input);
cout << "Vector Contains : ";
for (unsigned int i = 0; i < userInput.size(); i++)
{
cout << userInput[i] + 2;
}
system("pause>nul");
return 0;
}
The reason you're only taking in one input is because you're only taking in one int from std::cin. The other ints are still remaining in the stream. You should do this:
while(/*we still have stuff to extract*/)
{
std::cin >> input;
userInput.push_back(input);
}
However, we still need to know when to stop. Since we're only expecting one line of input from the user, we can do std::cin.peek() != '\n' to check if we've reached the point where the user pressed the Enter key earlier.
Thank you for reading.
The standard extraction operator for int expects whitespace as the separator between items so you don't need to do anything special there. Just read ints, put them in your vector, do the addition, and print out the results. Assuming you've already read n for the count, the real work could look something like this:
std::copy_n (std::istream_iterator<int>(std::cin),
n,
std::back_inserter(your_vector));
std::transform(your_vector.begin(), your_vector.end(),
std::ostream_iterator<int>(std::cout, " "),
[](int i){ return i + 2; });
Try the following
#include <iostream>
#include <vector>
#include <cstdlib>
int main()
{
std::cout << "How many numbers are you going to enter ? :";
size_t n = 0;
std::cin >> n;
std::vector<int> v( n );
std::cout << "Enter " << n << " numbers : " << std::endl;
int x;
for ( size_t i = 0; i < n && std::cin >> x; i++ ) v[i] = x;
for ( int x : v ) std::cout << x + 2 << ' ';
std::cout << std::endl;
std::system( "pause>nul" );
return 0;
}
If to input
4
11 45 71 24
the output will be
13 47 73 26
Other approach is to use standard function std::getline and std::istringstream instead of the operator >>
For example
#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <sstream>
#include <limits>
int main()
{
std::cout << "How many numbers are you going to enter ? :";
size_t n = 0;
std::cin >> n;
std::vector<int> v( n );
std::cout << "Enter " << n << " numbers : " << std::endl;
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
std::string s;
std::getline( std::cin, s );
std::istringstream is( s );
int x;
for ( size_t i = 0; i < n && is >> x; i++ ) v[i] = x;
for ( int x : v ) std::cout << x + 2 << ' ';
std::cout << std::endl;
std::system( "pause>nul" );
return 0;
}