So I got this code, I input three numbers. Now I want to display them in a for loop. From smallest to biggest, and in another loop from biggest to smallest. How can I do this?
int main()
{
int num1, num2, num3;
cout << "Enter first num" << endl;
cin >> num1;
cout << "Enter second num" << endl;
cin >> num2;
cout << "Enter third num" << endl;
cin >> num3;
}
I have done this like this but I think it's not a proper way to do it.
for(int i = 0; i <= 0; i++) {
cout << num1;
cout << num2;
cout << num3;
}
for(int i = 0; i <= 0; i++) {
cout << num3;
cout << num2;
cout << num1;
}
Edit:
is this better?
int main()
{
int numbers[3];
cout << "Enter first num" << endl;
cin >> numbers[0];
cout << "Enter second num" << endl;
cin >> numbers[1];
cout << "Enter third num" << endl;
cin >> numbers[2];
for (int i = 0; i <= 2; i++)
{
cout << numbers[i];
}
for (int i = 2; i >= 0; i--)
{
cout << numbers[i];
}
return 0;
}
What you are trying to do is very common in programming languages. I.e. enter data, process it and output it in one form or another.
A loop is what you use if you want to execute a piece of code a number of times... a number more than 1 that is. In your first example you execute the loop once, making the extra lines of code a bit redundant.
You already updated your code, showing you quickly realized how to used arrays. These types of arrays (i.e. int numbers[3];) are often referred to as C-style arrays, as they were inherited from C. In C++ we can now use std::array<int, 3> numbers;, which more adheres to the C++ style of working. (The std:: part of the type name indicates the type is define in the standard library namespace. The type is part of the C++ language standard.)
The problem with these two types is that they have a static(=fixed) size. I.e. the size has to be know at compile time. This can be quite a limitation if you don't know how many items the user wants to enter. However, the C++ standard defines other container types which can hold a variable amount of items. Of these, std::vector is the dynamic (variable) size counterpart of the array: these both store their items sequentially in memory.
So you can for instance use a loop to add (to the back = push_back()) a number of elements selected by the user to the vector.
#include <vector>
#include <iostream>
[...]
std::vector<int> numbers;
std::cout << "How many numbers do you want to enter?\n";
int N;
std::cin >> N;
numbers.reserve(N); // good practice to reserve memory if you know the number of elements
for (int i = 0; i < N; ++i) {
std::cout << "Enter a number: ";
int number;
std::cin >> number;
numbers.push_back(number);
}
[...]
Note that there is no check on the input: e.g. if the user would enter "-1" after the first question, things would break. I will not consider handling user error in my answer.
You can already see some code duplication in here: cout, type definition, cin. You can extract this in a separate function.
#include <string>
[...]
int ReadUserInput(std::string const& message) {
std::cout << message;
int value;
std::cin >> value;
return value;
}
or even better, you make a function template. I.e. a template for a function: the compiler will generate implementations of this function for you, depending on the type T inferred. I also use the std::string_view now, which can view to different types of strings (std::string, char*)
#include <string_view>
[...]
template<typename T>
T ReadUserInput(std::string_view message = "") {
if (!message.empty()) std::cout << message; //only print is there's an actual message
T value;
std::cin >> value;
return value;
}
Next, the C++ library has more to offer, including a number of algorithms that are commonly used in programming. One of these is a generator that repeatedly calls a function, of which the result is used to assign successive elements in a container. The object that points to a specific element in the container is called an iterator. The C++ standard library offers a convenient iterator type that executes a push_back: the std::back_inserter. The previous code can now be reduced to:
int const N = ReadUserInput<int>("How many numbers do you want to enter?\n");
std::vector<int> numbers;
numbers.reserve(N); // good practice to reserve memory if you know the number of elements
std::generate_n(back_inserter(numbers), N, ReadUserInputGenerator<int>("Enter a number: "));
"But wait", you might ask, "what is this ReadUserInputGenerator?". Well, to make the generate_n work, you need to pass a pointer/handle to a generator function, which is then executed for each element. If we'd just call ReadUserInput<int>("Enter a number: "), then the function would already have been evaluated. So we need to add another intermediate function object that makes this generator function. In the passed we would make a class for this
template<typename T>
class ReadUserInputGenerator {
private:
std::string_view message;
public:
ReadUserInputGenerator(std::string_view message = "") : message(message) {}
T operator()() const { return ReadUserInput(message); }
};
... but now we can do using lambda expressions
template<typename T>
auto ReadUserInputGenerator = [](std::string_view message = "") {
return [message]() { return ReadUserInput<T>(message); };
};
(note to more experienced readers: I'm not really sure about passing string_view by value. I based it on this)
SOOOOO, now we finally have our input. Next you wanted to sort it. Again, this is a common operation. There are actually many ways to sort a collection a values and it is a good excersize to implement these yourself... However, like I mentioned previously, as these kind of operations are common in programming, the C++ standard library actually offers an algorithm for sorting: std::sort.
std::sort(begin(numbers), end(numbers));
^ here begin and end refer to iterators pointing to the begin and end (or actually one past the end) of your vector. You could sort only part of your vector this way. However, the most common case is just begin to end, so in C++20 they've introduced the ranges algorithms, and the previous statement can be reduced to
std::ranges::sort(numbers);
... AAAND now its sorted... printing is next. You can print using a loop... but even there you will have a number of choices. And indexed loop:
for (int i = 0; i < numbers.size(); ++i) {
std::cout << numbers[i] << ' ';
}
An iterator based for loop:
for (auto it = cbegin(numbers); it != cend(numbers); ++it) {
std::cout << *it << ' ';
}
Note: the 'c' before begin and end denote that it is a "const" qualified iterator, i.e. it may not modify the contents of the object it points to.
Or a range based for loop:
for (int number : numbers) {
std::cout << number << ' ';
}
There is also a special convenience iterator type that can push to the cout: std::ostream_iterator. You can copy the vector to this iterator using the algorithm std::copy
std::copy(cbegin(numbers), cend(numbers), std::ostream_iterator<int>(std::cout, " "));
Note, the second argument of the ostream_iterator is the delimiter, i.e. the string appended after each element. Of course there's also a C++20 ranges version.
std::ranges::copy(numbers, std::ostream_iterator<int>(std::cout, " "));
... FINALLY reversing.
One option is just to reverse all elements in the vector and print them out again using one of the above mentioned methods. There's of course an algorithm to do so: std::reverse.
std::reverse(begin(numbers), end(numbers));
However, this operation modifies the contents of the container(vector), which might be costly. If you don't want to to this, you'll have to loop though your vector in reverse order
for (int i = numbers.size() - 1; i >= 0; --i) {
std::cout << numbers[i] << ' ';
}
This looks complex, and it's easy to make errors.
You could instead use the reverse iterators of vector, to traverse through the vector in reverse order: (you need to add an 'r' to the begin/end)
for (auto it = crbegin(numbers); it != crend(numbers); ++it) {
std::cout << *it << ' ';
}
or
std::copy(crbegin(numbers), crend(numbers), std::ostream_iterator<int>(std::cout, " "));
For C++20, there's no range operation to reverse the vector. However, they introduced "views" that are used to observe the values in the vector in a specific way. One such a way is "observe it in reverse order": std::ranges::view::reverse. So in C++20 you will be able to do:
for (int number : numbers | std::views::reverse) {
std::cout << number << ' ';
}
or
std::ranges::copy(numbers | std::views::reverse, std::ostream_iterator<int>(std::cout, " "));
which both don't modify numbers.
The end code could look a little bit something like this (pre C++20 version):
#include <vector>
#include <iostream>
#include <string_view>
#include <iterator>
#include <algorithm>
template<typename T>
T ReadUserInput(std::string_view message = "") {
if (!message.empty()) std::cout << message; //only print is there's an actual message
T value;
std::cin >> value;
return value;
}
template<typename T>
auto ReadUserInputGenerator = [](std::string_view message = "") {
return [message]() { return ReadUserInput<T>(message); };
};
int main() {
int const N = ReadUserInput<int>("How many numbers do you want to enter?\n");
std::vector<int> numbers;
numbers.reserve(N); // good practice to reserve memory if you know the number of elements
std::generate_n(back_inserter(numbers), N, ReadUserInputGenerator<int>("Enter a number: "));
std::sort(begin(numbers), end(numbers));
std::copy(cbegin(numbers), cend(numbers), std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
std::copy(crbegin(numbers), crend(numbers), std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
}
Given that the input doesn't seem to have any meaning other than "some numbers", you should use a container, and the obvious choice would be:
std::vector<int> nums;
From c++20, you don't needs loops at all for this problem, because you can use ranges:
#include<ranges>
namespace rs = std::ranges;
namespace rv = std::views;
and now you can read in numbers like this:
rs::copy_n(std::istream_iterator<int>(std::cin), 3,
std::back_inserter(nums));
I'm not sure if you want to use the order that the user inputs the numbers, but if you want the actual smallest to largest, you can do:
rs::sort(nums);
Now to print out the numbers:
rs::copy(nums,
std::ostream_iterator<int>(std::cout, " "));
and in reverse:
rs::copy(nums | rv::reverse,
std::ostream_iterator<int>(std::cout, " "));
Here's a demo.
You don't need a loop, the one you have it's not really a loop in the sense that it only cycles once, you can use a chained ostream:
cout << num1 << " " << num2 << " " << num3 << "\n";
And
cout << num3 << " " << num2 << " " << num1 << "\n";
But if you want print them sorted by value and you can't use some container where you can apply a sorting algorithm, you'll need some conditionals.
EDIT: Is this better?
Storing it in an array makes it easier to deal with the data, for instance, it will allow you to sort it by value using something as simple as <algorithm> library std::sort.
This question already has answers here:
How do I print out the contents of a vector?
(31 answers)
Closed 5 years ago.
I am trying to get a feel for C++, and I want to either print the contents of a vector, or, to confirm my program is correct, I could add the contents of my vector and print the result.
Here is my code:
#include <iostream>
#include <vector>
using std::vector;
using std::cin;
using std::cout;
int main(){
int n;
vector<int> result;
cin >> n;
vector<int> numbers(n);
for(int i = 0; i < n; ++i){
cin >> numbers[i];
}
result = numbers;
cout << result;
return 0;
}
I found some solutions online for printing a vector, but I didn't understand what the code was doing, so I am hoping someone can help.
As you mentioned "I did not understand what the code is doing", let me briefly describe how to iterate through a container:
The long way:
vector<int> result = { 1,2,3 };
for (vector<int>::iterator it = result.begin(); it != result.end() ; it++) {
int i = *it;
cout << i << " ";
}
Each container provides an iterator, which you can think of a pointer moving forward along the elements of the container. begin() returns a pointer to the first element, end() returns a pointer to 1 past the last element. Dereferencing the iterator gives the actual value.
For above long way, with range-based for loops, C++ provides a shorthand notation with about the same meaning (i.e. it makes use of the iterator-concept but is less "clumsy" in notation):
for (auto i : result) {
cout << i << " ";
}
Try it out; hope it helps.
you can print the vector content by making a loop the print every index in the vector size
like
for(int i=0;i<numbers.size();i++){
cout<<numbers[i];
}
the loop will print every index until the end of the vector
My goal is to try and create a program that takes in grades in percents and multiply it with their weight value (either in decimal form or percent form). The equation is basically:
Overall grade = (grade1*weightInDecimal1)+(grade2*weightInDecimal2)+(grade3*weightInDecimal3)+...
or
Overall grade = (grade1*weight%1)+(grade2*weight%2)+(grade3*weight%3)+...
Is there a way to store the inputs and then recall it later in the code? Or possibly a more efficient way?
I also want to try and make a dynamic array. I want to make a program that asks the user for how many assignments they have and makes an array based on that. That way it's not stuck at 4 assignments
#include <string>
#include <iostream>
using namespace std;
int main() {
int numbers[4][2];
for(int i=0;i<4;i++)
{
cout<<"Grade #"<<i<<endl;
cin>>numbers[i][0];
cout<<"Weight for grade #"<<i<<":"<<endl;
cin>>numbers[i][1];
}
for (int i = 0; i<4; i++)
{
cout << "|" << numbers[i][0]*numbers[i][1]<< "|";
}
system ("PAUSE");
return 0;
}
This is what structs are for
#include <string>
#include <iostream>
#include <array>
using namespace std;
struct entry {
int grade;
int weight;
int gradeWeight; //grade*weight
};
int main() {
array<entry,4> numbers;
for(int i=0;i<numbers.max_size();i++)
{
cout<<"Grade #"<<i<<endl;
cin>>numbers[i].grade;
cout<<"Weight for grade #"<<i<<":"<<endl;
cin>>numbers[i].weight;
}
for (int i = 0; i<numbers.max_size(); i++)
{
numbers[i].gradeWeight = numbers[i].grade*numbers[i].weight;
cout << "|" << numbers[i].gradeWeight << "|";
}
system ("PAUSE");
return 0;
}
This way you can also increase the amount of numbers by just increasing the array size.
As pointed by others, if you ask the user for how many assignments they have, std::array is a wrong container because it's dimension is fixed at compile time.
As others, I discurage the use of direct memory allocation but the use of std::vector to manage it.
I just suggest the use of reserve() (method of std::vector), when you know how many assignments.
The following is a full example using, instead a couple of std::vector of int, a single std::vector of std::pair<int, int>
#include <utility>
#include <vector>
#include <iostream>
int main()
{
int valG, valW;
std::size_t dim;
std::vector<std::pair<int, int>> vec;
std::cout << "How many grade/weight couples? ";
std::cin >> dim;
vec.reserve(dim);
for ( auto i = 0U ; i < dim ; ++i )
{
std::cout << "Grade #" << i << "? " << std::endl;
std::cin >> valG;
std::cout << "Weight for grade #" << i << "? " << std::endl;
std::cin >> valW;
vec.emplace_back(valG, valW);
}
for ( auto const & p : vec )
std::cout << '|' << (p.first * p.second) << '|';
std::cout << std::endl;
return 0;
}
There are many reasons to avoid using arrays (dynamic or otherwise). See for example Stroustrup's FAQ entry What's wrong with arrays? As Greg suggests in the comments you will most likely write better quality code if you use a container like std::vector.
If you can calculate or input the size of your container before allocating it you can (if you wish) pass that size to the constructor ...
auto syze{ 0 };
auto initialValue{ 0 };
// calculate or input syze
. . .
// dynamically allocate an "array"
// of ints and an "array" of floats
std::vector<int> grades(syze, initialValue);
std::vector<float> weights(syze, initialValue);
On the other hand if you prefer to use a container that dynamically grows to hold data as it arrives you can do that too...
// dynamically allocate an empty "array"
// of ints and an empty "array" of floats
std::vector<int> grades;
std::vector<float> weights;
while (...condition...)
{
std::cin >> g; // input a grade ...
std::cin >> w; // ... and a weight
// grow the containers by adding
// one item at the end of each
grades.emplace_back(g);
weights.emplace_back(w);
}
Update
I should have pointed out how to calculate the result from the two vectors. You can calculate your overall grade with just one more line of code by using std::inner_product from the STL's <numeric> header. Note that in the code below the last argument is 0.0 (rather than just 0) so that std::inner_product returns a double rather than an int. That avoids any risk of float values being truncated to int (and avoids some pretty ugly warnings from the compiler).
auto overallGrade = std::inner_product(grades.begin(), grades.end(), weights.begin(), 0.0);
I am a beginner and I would like to ask you something.
We have an array whose size depends on value input by user in a variable ‘arraysize’. Look at below code and comments please, is it a correct way to achieve this said be behaviour?
int * myArray = NULL;
int arraySize;
cout << "Enter array size: ";
cin >> arraySize;
myArray = new int[arraySize];
delete [] myArray;
The earlier answer was a community wiki. Since you asked for an example, here's a more detailed answer.
A std::vector is a class belonging to the standard template library read in detail.
//since you used "using namespace std;" I'm omitting the "std::"
Declaration
vector< int > v; //creates a vector of integers
vector< double > vd; //vector of double values
This is quite similar to int a[/*any number*/].
Inserting values
v.push_back(5); //adds 5 to the end of the vector (or array of variable size)
With the above two lines you dont need to know in advance how many numbers you'll have to store.
One more sample code.
#include <iostream>
#include <vector>
int main ()
{
std::vector<int> myvector;
int myint;
std::cout << "Please enter some integers (enter 0 to end):\n";
do {
std::cin >> myint;
myvector.push_back (myint);
} while (myint);
std::cout << "myvector stores " << int(myvector.size()) << " numbers.\n";
return 0;
}
This program reads values and saves to myvector till 0 is entered in input.
Iteration
std::vector<int>::size_type sz = myvector.size(); //even int works here
// assign some values:
for (unsigned int i=0; i<sz; i++) myvector[i]=i;
Deletion
v.pop_back(); //removes last element
Use std::vector as a C++ best practice.
I'm doing some exercises with vectors. I created a function that fill a vector with defined size but when I tried to make it n size, the vector apparently is filled with trash memory, it shows: 0x23fe20, and my code crash when I try to use the vector.
#include <iostream>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
using namespace std;
int cargavn(int vec[]) // fill vector
{
int i, t;
cout << "vector size: ";
cin >> t;
for(i = 0 ; i <= t-1; i++)
{
cout << "v["<< i <<"]=";
cin >> vec[i];
}
return (1);
}
int main()
{
int vec[10]; // the vector, size here wont matter
cargavn(vec); // call fill vector n positions
cout << vec; // to test if the vector is well filled
system("PAUSE");
}
you are exprecting cout << vec to somehow pretty print the vector. It wont, it just prints its address
You need to loop over the contents and print each element
for(int i =0 ; i < 10 ; i++)
{
cout << vec[i];
}
Here's how it would look using modern C++:
#include <iostream>
#include <vector>
using namespace std;
void cargavn(vector<int> &vec)
{
int t;
cout << "vector size: ";
cin >> t;
for(int i = 0; t > 0; ++i, --t)
{
cout << "v["<< i <<"]=";
int v;
cin >> v;
vec.push_back(v);
}
}
ostream &operator<<(ostream &s, vector<int> const &vec)
{
s << '{';
bool first = true;
for (int v : vec)
{
if (!first)
{
s << ", ";
}
s << v;
first = false;
}
return s << '}';
}
int main()
{
vector<int> vec;
cargavn(vec);
cout << vec;
system("PAUSE");
return 0;
}
Things to understand about this version compared to yours:
Unnecessary includes are ommitted.
Prefer C++ containers like vector over C style arrays.
Use dynamically sized containers when they need to hold an arbitrary number of values provided by the user instead of fixed-size containers that break when the user enters too much data. See the rule of 0, 1, infinity.
When all control paths of a function return the same value, then the returned value is pointless and can be omitted. Particularly if none of the callers even bothers to check the return value. I suspect you had the intention of using the return value to indicate some kind of unexpected error. This is a C-style approach to error handling. C++ uses exceptions to deal with unexpected errors.
Overload operator<< to extend the stream insertion operator to decide how containers and your own custom types should be formatted. The standard library doesn't provide any such insertion operator for vector because there isn't any universally agreed upon way to decide how a vector of values should be formatted. So you decide this for yourself.
It is good form for main to return a value, even though this is not technically required.