Print numbers in range of two user-input values with while loop - c++

I feel like I might be missing something here, but something is telling me that I might just be making this more difficult that it has to be, but from the book, "C++ Primer, 5th ed.," I'm stuck on this problem:
Exercise 1.11: Write a program that prompts the user for two integers.
Print each number in the range specified by those two integers.
Up until this time in the book, the only loop being used is the while loop, and no conditional expressions, like if, have been introduced. The problem would be simple if it were not for the fact that a user could put the values into the integers asked for in ascending or descending order, so simple subtraction WOULD find the difference, but without testing which way to increment.
How could I absolutely print the range between the numbers, guaranteeing not to just increment towards infinity without testing the outcome of such math and/or without comparing the two numbers? This is what I have; it works when the first value: v1 is less than or equal to the second: v2, but not otherwise:
#include <iostream>
int main()
{
int v1 = 0, v2 = 0;
std::cout << "Enter two integers to find numbers in their range (inclusive): "
<< endl;
std::cin >> v1 >> v2;
while (v1 <= v2)
{
std::cout << v1;
++ v1;
}
return 0;
}
Any help would be greatly appreciated!

Here is a simple rewrite where you use min and max to determine the range you want to iterate on:
#include <iostream>
int main()
{
int v1 = 0, v2 = 0;
std::cout << "Enter two integers to find numbers in their range (inclusive): " << std::endl;
std::cin >> v1 >> v2;
int current = std::min(v1, v2);
int max = std::max(v1, v2);
while (current <= max)
{
std::cout << current << std::endl;
++ current;
}
return 0;
}
This also allows you to keep the two inputs "intact", because you're using another variable to iterate on the values.
Also note that the ++current could be done on the exact same line it is printed if it was replaced by current++. The later would return the current value of current and THEN increment it.
Edit
Here's what Michael suggested I believe, in working code:
#include <iostream>
int main()
{
int v1 = 0, v2 = 0;
std::cout << "Enter two integers to find numbers in their range (inclusive): " << std::endl;
std::cin >> v1 >> v2;
int increment = (v2 - v1) / std::abs(v2 - v1);
int current = v1;
int max = v2 + increment;
while (current != max)
{
std::cout << current << std::endl;
current += increment;
}
return 0;
}

You can use (v2-v1)/abs(v2-v1) or some such for increment. (provided they're not equal). And for loop condition you may check if current number is still in between, like (v1<=v && v<=v2) || (v2<=v && v<=v1).
And to avoid the case of zero, I'd turn it into do while loop and use v1!=v2 && ... as a condition.
To sum it all up:
int v = v1;
do {
std::cout << v << std::endl;
}while( v1!=v2 && ( (v1<=(v+=(v2-v1)/std::abs(v2-v1)) && v<=v2) || (v2<=v && v<=v1) ) );
P.S. I trust you can resolve the input issue mentioned in comments and in the other answer on your own.

I tried my amateur way and got the result. I hope it will be helpful.
#include <iostream>
using namespace std;
int main()
{
int a;
int b;
int val;
cout << "Please enter small value "<< endl;
cin >> a;
cout << "Please enter bigger value than the last one " << endl;
cin >> b;
while (val>a)
{
val = --b;
cout << "The numbers between a & b are "<< val << endl;
}
return 0;
}

Since I still remember this problem from the C++ Primer, I think the way they wanted you to solve it was with the basics of programming they provided you until then.
In my opinion it should have been solved like this, if this was this exact problem from this book:
#include <iostream>
int main()
{
int v1 = 0, v2 = 0;
std::cout << "Enter 2 numbers" << std::endl;
std::cin >> v1 >> v2;
while (v1 < v2) {
std::cout << v1 << std::endl;
++v1;
}
}

Related

Expression: vector erase iterator outside range when using vector.erase()

I am new to C++ and was trying to write a program that takes the lowest and the highest numbers in a vector, takes them away from the vector and proceeds to calculate an average with the rest of the numbers.
Now while I understand that I could do it after the numbers have been entered, I wanted to challenge myself and carry out these checks as the numbers were entered one by one. I was looking around but I couldn't find another person with the exact issue I am having (since I am using vector.end() - 1).
Below is my code and the error that it is giving me. Any guidance is much appreciated.
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <numeric>
#include <limits.h>
using namespace std;
typedef vector<int>::iterator iter;
int main() {
cout << "Please enter the series of scores: \n";
// Read numbers from the standard input
// and store them in a vector
vector<int> scoreVector;
int x = 0;
int count = 0;
// Assign the lowest possible value to the maximum possible integer so that any value entered initially will be lower that INT_MAX
int lowestValue = INT_MAX;
int highestValue = 0;
iter lowestValueIndex;
iter highestValueIndex;
// Every time a number is entered, the program checks to see if it meets the criteria for the lowest or highest number entered so far
while (cin >> x) {
scoreVector.push_back(x);
if (x > highestValue) {
highestValueIndex = scoreVector.end() - 1;
highestValue = x;
}
if (x < lowestValue) {
lowestValueIndex = scoreVector.end() - 1;
lowestValue = x;
}
}
// Calculate the vector size
auto n = scoreVector.size();
if (n > 2) {
cout << "\nThe lowest value is:" << lowestValue << "\nThe highest value is: " << highestValue << ". These values have been taken out." << '\n';
// Remove the two values from the vector
scoreVector.erase(lowestValueIndex);
scoreVector.erase(highestValueIndex);
// Calculate the average
auto average = accumulate(scoreVector.begin(), scoreVector.end(), 0.0) / n;
cout << "\naverage = " << average << '\n';
}
return 0;
}
Inside your while loop, you are taking iterators to scoreVector. However, every time you do a push_back on a vector, all iterators to it are invalidated. This means that when you exit your while loop, at least one if not both iterators are dangling. Passing those iterators to .erase then invokes undefined behavior.
Instead, you should separate out the reading of the variables, and computation of the iterators that you want to erase:
while (cin >> x) {
scoreVector.push_back(x);
}
iter lowestValueIndex = std::min_element(scoreVector.begin(), scoreVector.end());
scoreVector.erase(lowestValueIndex);
iter highestValueIndex = std::max_element(scoreVector.begin(), scoreVector.end());
scoreVector.erase(highestValueIndex);
According to Iterator invalidation rules, scoreVector.push_back(x); may invalidate iterators taken before that by causing reallocation.
You should save indice instead of iterators as indice.
Also be careful because erase will shift following elements and it may affect indice of the element to be erased.
Try this:
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <numeric>
#include <limits.h>
using namespace std;
typedef vector<int>::iterator iter;
int main() {
cout << "Please enter the series of scores: \n";
// Read numbers from the standard input
// and store them in a vector
vector<int> scoreVector;
int x = 0;
int count = 0;
// Assign the lowest possible value to the maximum possible integer so that any value entered initially will be lower that INT_MAX
int lowestValue = INT_MAX;
int highestValue = 0;
size_t lowestValueIndex = 0;
size_t highestValueIndex = 0;
// Every time a number is entered, the program checks to see if it meets the criteria for the lowest or highest number entered so far
while (cin >> x) {
scoreVector.push_back(x);
if (x > highestValue) {
highestValueIndex = scoreVector.size() - 1;
highestValue = x;
}
if (x < lowestValue) {
lowestValueIndex = scoreVector.size() - 1;
lowestValue = x;
}
}
// Calculate the vector size
auto n = scoreVector.size();
if (n > 2) {
cout << "\nThe lowest value is:" << lowestValue << "\nThe highest value is: " << highestValue << ". These values have been taken out." << '\n';
// Remove the two values from the vector
scoreVector.erase(std::next(scoreVector.begin(), lowestValueIndex));
if (lowestValueIndex < highestValueIndex) highestValueIndex--;
scoreVector.erase(std::next(scoreVector.begin(), highestValueIndex));
// Calculate the average
auto average = accumulate(scoreVector.begin(), scoreVector.end(), 0.0) / n;
cout << "\naverage = " << average << '\n';
}
return 0;
}

An exercise asks me to change the body of the loop. What does it mean?

I am fairly new to C++ still, as well as programming and the terms used. I'm learning off of "Programming: Principles and Practice Using C++" (as was gifted to me) and I ran into a problem on a Drill at the end of chapter four. The drill is split into twelve exercises, where the first five are as follows:
Write a program that consists of a while-loop that (each time around the loop) reads in two ints and then prints them. Exit the
program when a terminating '|' is entered.
Change the program to write out the smaller value is: followed by the smaller of the numbers and the larger value is: followed by the
larger value.
Augment the program so that it writes the line the numbers are equal (only) if they are equal.
Change the program so that it uses doubles instead of ints.
Change the program so that it writes out the numbers are almost equal after writing out which is the larger and the smaller if the two
numbers differ by less than 1.0/100.
I've dealt with those exercises, but now I don't quite get what to do in the next exercise:
Now change the body of the loop so that it reads just one double each time around. Define two variables to keep track of which is the smallest and which is the largest value you have
seen so far. Each time through the loop write out the value entered. If it’s the smallest so far, write the smallest so far after the number. If it is the largest so far, write the largest so far after the number.
I don't get it. What should I do with the loop? What's exercise 6 actually about?
My code I have made up so far from step five is as follows:
#include <iostream>
#include <vector>
#include <algorithm>
//Name
int main()
{
char terminate = ' ';
double one = 0.0;
double two = 0.0;
int one_i = one;
int two_i = two;
while (terminate != '|')
{
std::cout << "Input two numbers, follow each one by enter: " << std::endl;
std::cin >> one;
std::cin >> two;
if (one == two)
{
std::cout << "The two numbers are equal to each other." << std::endl;
std::cout << "To terminate this program, type \"|\" into the system followed by pressing enter twice." << std::endl;
std::cin >> terminate;
if (terminate == '|')
{
break;
}
}
std::cout << "Here is the larger value: ";
if (one > two)
{
std::cout << one << std::endl;
}
else
{
if (two > one)
{
std::cout << two << std::endl;
}
}
std::cout << "Here is the smaller value: ";
if (one < two)
{
std::cout << one << std::endl;
if (one_i == two_i || two_i == one_i)
{
std::wcout << "The numbers are almost equal." << std::endl;
}
}
else
{
if (two < one)
{
std::cout << two << std::endl;
if (one_i == two_i || two_i == one_i)
{
std::wcout << "The numbers are almost equal." << std::endl;
}
}
}
std::cout << "To terminate this program, type \"|\" into the system followed by pressing enter twice." << std::endl;
std::cin >> terminate;
}
}
I attempted to figure out the problem if this code helps any of you see as to what degree I'm confused on.
#include <iostream>
#include <vector>
#include <algorithm>
//Name
int main()
{
char terminate = ' ';
std::vector<double>num_size;
while (terminate != '|')
{
std::cout << "Type in a number: " << std::endl;
for (double num; std::cin >> num;)
{
num_size.push_back(num);
std::sort(num_size.begin(), num_size.end());
}
std::cout << "To terminate this program, type \"|\" into the system followed by pressing enter twice." << std::endl;
std::cin >> terminate;
}
}
Well, you didn't finish step 5. 999 and 1000 are almost equal (difference < 1%).
Ignoring that, your second fragment is a good start at producing the behavior wanted in step 6 but ignores the prescribed method. Yes, a sorted vector has a .front() and a .back() which are the respective minimum and maximum, but step 6 specifically told you to use two variables instead of a whole vector.
So double max = std::numeric_limits<double>::max(); double min = -max; and from there on you should be able to figure it out.
You want something like:
double my_max = numeric_limits<double>::max();
double my_min = -1 * numeric_limits<double>::max();
while (...) {
...
my_min = min(my_min, one);
my_min = min(my_min, two);
my_max = max(my_max, one);
my_max = max(my_max, two);

Trying to make a while Loop that subtracts a number until it reaches desired value and if subtraction surpasses desired value, display it and stop

I'm new to programming and to c++ so I know this is probably a silly question but I would really appreciate the help. just as the tittle says, I'm trying to make a subtraction while type loop that reaches a desired value, in this case: 0
The code uses two random numbers from the user input. The first number is the minuend, the second is the subtrahend
However, the problem that I'm having is that if subtraction surpasses desired value, the loop will not display it and the user will see displayed a number higher value than 0. I want to fix so it displays the negative number closest to 0 and then stop. Here's the code:
#include <iostream>
using namespace std;
int main()
{
int a;
int b;
cout <<" enter a: ";
cin >> a;
cout << "enter b: ";
cin >> b;
while ( a > 0 )
{
cout << a << '\n';
a= a-b;
}
return 0;
}
What am I doing wrong, how can I fix it? Thanks
You're printing a before decreasing it. Try switching the statements inside your loop like so:
while ( a > 0 )
{
a = a - b;
cout << a << '\n';
}
You could just add
cout << a << '\n';
again after your loop - you know you have the right value then. Or you could possibly avoid duplicating that line by switching to using a do ... while loop.
Hi i just switched this code:
while ( a > 0 )
{
cout << a << '\n';
a= a-b;
}
to this and it worked as you explained:
while ( a > 0 )
{
a= a-b;
cout << a << '\n';
}

C++ primer exercise 1.19, first attempt at the "if" statement

In an earlier exercise i wrote a program that took two inputs and printed out the numbers between the two numbers. in exercise 1.19, i am asked to rewrite the program so that it can handle the issue of the first number being smaller than the second number. i am asking 2 questions:
i feel as though i played a dirty trick with the if statement that
just switches the numbers around in the correct order. is that bad
coding?
what i wrote works, it "handles" the issue of the user inputting a
number that is smaller than the second. however since i am very new to
programming and only in chapter 1 of C++ primer. am i missing
something important here that would cause me to write the code
"better" (EX: if i understood X concept then i would wrote the "if"
statement better/differently)
int main()
{
int v1 = 0, v2 = 0, e1 = 0, e2 = 0, sum = 0;
std::cout << "Input first integer: ";
std::cin >> v1; std::cout << std::endl;
e1 = v1;
std::cout << "Input secound integer: ";
std::cin >> v2; std::cout << std:: endl;
if (v1 > v2)
{
e1 = v1;
e2 = v2;
v1 = e2;
v2 = e1;
e1 = v1;
}
while (v1 <= v2)
{
sum += v1;
++v1;
}
std::cout << "The inclusive sum of " << e1 << " and " << v2 << " is "
<< sum;
return 0;
}
To answer your second question (and indirectly your first) I recommend that you use the swap function from the C++ Standard Library. You can check it out here. In general, using STL code is better than writing functions yourself (for obvious reasons).
So to implement it in your code, you'll need to first:
#include <algorithm>
Then in the body of that first if statement, just say:
std::swap(v1, v2);
You can use only a single extra variable, and simplify your if considerably.
int v1 = 0, v2 = 0, sum = 0;
std::cout << "Input first integer: ";
std::cin >> v1; std::cout << std::endl;
std::cout << "Input secound integer: ";
std::cin >> v2; std::cout << std:: endl;
if (v1 > v2)
{
int tmp = v1; // Store v1 in a temp variable
v1 = v2; // Move v2's value into v1
v2 = tmp; // Move temp variable into v2
}
What I did for this is used an if else
int main()
{
int val1 = 0, val2 = 0, sum = 0;
std::cout << "Enter in 2 numbers " << std::endl;
std::cin >> val1;
std::cin >> val2;
// if the first value is smaller than the second then do below
if(val1<val2)
{
sum = val1; // setting sum equal to the first value entered
while(val1<=val2) // run while val1 is less than or equal to val2
{
std::cout << sum << std::endl; // printing sum
sum++; // adding +1 to sum
val1++; // adding +1 to val1 otherwise it will print sum to infinity
}
}
else // If the second value is smaller than the first entered do below
{
sum = val2; // setting sum equal to the second value entered
while(val2<=val1)
{
std::cout << sum << std::endl;
sum++; // adding +1 to sum
val2++; // adding +1 to val2 otherwise it will print sum to infinity
}
}
std::cout << "woot!" << std::endl;
return 0;
}
It gets rid of the swapping. Took me a little while to get it. I didn't think I needed to add the val1++ or val2++ so it was just printing out numbers as fast as possible. Cool to look at, but not what I wanted. Hope this helps somebody!
Note: Mine is a little different from what the problem is asking for. Adding a set of numbers together but I believe the same logic can be used.

creating a sum function for summing only part of a vector

Obviously I need a sum function for this and accumulate will not cut it
I need to create program - a vector - with n number of elements the user can prescribe - and the sum function can only sum POSITIVE elements even though the user can enter negative elements as well...
In the computeSum function I also need to add a "success" to the whole group
computeSum (dataVec, howMany, total, sucess);
and create a parameter for people who enter - all negative numbers but want to sum them but are unable to because there are no positive numbers
if (success) {
cout << "The sum is " << total << endl;
}
else {
cerr << "Oops, you cannot add these elements.";
}
So here is what I got
#include <iostream>
#include <vector> // need this in order to use vectors in the program
using namespace std;
int main()
{
vector<double> dataVec;
double i, n, howMany, total;
cout << "How many numbers would you like to put into the vector?";
cin >> n;
dataVec.resize(n);
for(vector<double>::size_type i=0;i < n;i++)
{
cout << "Enter the numbers: \n";
cin >> dataVec[i];
}
cout << "How many POSITIVE numbers would you like to sum?";
cin >> howMany;
cout << computeSum (dataVec, howMany, total);
}
double computeSum (vector<double> &Vec, howMany, total)
{
double total =0;
for(int i=0;i < howMany;i++)
total+=Vec[i];
return total;
}
I also seem to having trouble compiling just this - computeSum() is not being understood in int main(); howMany is not being understood in computerSum(); and on a gloabl scope total() and howMany() are undeclared (I guess that would mean i would need to decalre globally???)
In fact, accumulate will “cut it”, with an appropriate functor that only regards positive values:
int sum_positive(int first, int second) {
return first + (second > 0 ? second : 0);
}
…
std::accumulate(data.begin(), data.begin() + how_many, 0, sum_positive);
Getting on my hobby horse: Boost Range Adaptors. Hits the sweet point with me
#include <boost/range/adaptors.hpp>
#include <boost/range/numeric.hpp>
bool isnatural(int i) { return i>=0; }
using namespace boost::adaptors;
int main(int argc, char** args)
{
static const int data[] = { -130, -1543, 4018, 5542, -4389, 15266, };
std::cout << "sum: " << boost::accumulate(data | filtered(isnatural), 0) << std::endl;
return 0;
}
Output:
sum: 24826
With C++11 awesomeness1 spice:
std::cout << "sum: " << boost::accumulate(data
| filtered([] (int i) { return i>=0; }), 0) << std::endl;
1: to be honest, I really hate the clumsyness of lambda syntax:
having to specify the parameter type always
having to spell out the return statement to
For this scenario, it seems to that filtered([] (i) { i>=0 })
could be figured out by the compiler. Well, perhaps in c++22 :)
Your computeSum() function must appear above your main() function in the source file for it to be in scope. Also in your computeSum() function signature you haven't given types to the howMany and total variables. I'm guessing they should be double howMany and double total?