Fill vector with true value - c++

i would like to make all the values in a std::vector true. I wrote 2 methods: the first one worked but the second did not. It tells me myproj.exe has triggered a breakpoint. Do you know what is the problem?
This one works:
void first(std::vector<bool>& vect, unsigned int n)
{
for (unsigned int i = 0; i < n; i++)
{
vect.push_back(true);
}
}
This one does not:
void secound(std::vector<bool>& vect, unsigned int n)
{
for(unsigned int i = 0; i < n; i++)
{
vect[i] = true; //crash here
}
}

In first case you call push_back which automatically increases size of vector.
In second case you trying to access vect[i] which does not exist as size of vector is 0.
Easiest way to fill vector here would be
vect = std::vector<bool>(n, true);

You can use the following std::vector's overload:
vector(size_type count, const T& value, const Allocator& alloc = Allocator());
where the first argument is the size of the std::vector and the second argument is the initial value.
Full code:
#include <vector>
#include <iostream>
int main() {
std::vector<bool> v(10, true);
for (auto i : v) {
std::cout << std::boolalpha << i << std::endl;
}
return 0;
}
std::vector<bool> v(10, true); will create a vector with 10 boolean true values.
Check it out live.
If you want to reinitialize the std::vector, these are the following options:
use std::fill like this std::fill(v.begin(), v.end(), true);
use std::vector::resize like this v.resize(10, true); if the std::vector is already initialized
use std::vector::assign like this v.assign(10, true);

The problem with the second function implementation is that if the vector is empty or there are less elements than the value of the second parameter then you may not use the subscript operator. Otherwise you have undefined behavior.
Also there is a logical difference between the implementations.
In the first function implementation new elements are appended to already existent elements of the vector. In the second function implementation existent elements are overwritten.
But in any case the both function implementations look not good. You could do the same operation using one method of the class std::vector.
Here is a demonstrative program.
#include <iostream>
#include <iomanip>
#include <vector>
void reset( std::vector<bool> &v, size_t n, bool value = false )
{
v.assign( n, value );
}
int main()
{
std::vector<bool> v;
reset( v, 5);
for ( const auto item : v )
{
std::cout << std::boolalpha << item << ' ';
}
std::cout << '\n';
reset( v, 5, true );
for ( const auto item : v )
{
std::cout << std::boolalpha << item << ' ';
}
std::cout << '\n';
return 0;
}
The program output is
false false false false false
true true true true true

You can make use of std::fill to do this. This is more idiomatic c++ than reassignment
#include <algorithm>
#include <vector>
#include <iostream>
int main()
{
std::vector<bool> v(8);
std::fill(v.begin(), v.end(), true);
}

Related

Multiple Call Async for update vector or list in C++

I am stuck in multiple Async problems like that
example:
void updateList(vector<int> &list, int value){
list.push_back(value);
}
int main(){
vector<future<void>> asyncTasks;
vector<int> list;
for(int i = 0; i < 10; i ++){
asyncTasks.push_back(async(launch::async, updateList,i ));
}
for(auto &&f : asyncTasks){
f.get();
}
}
The problem is sometimes it throws errors about insert violent.
Can you give me any ideas ?
Well the problem is that you are doing 2 things at once in updateList:
Calculating a value based on the index given (by calculation I mean just using it)
Adding a value to a container
Doing the second in parallel does not make much sense, since you would have to serialize on the container, otherwise you get data races, which is the reason for your errors.
void updateList(vector<int> &list, int value){
list.push_back(value); //< Data race-> Undefined behavior -> Sometimes Crash
}
But we can do the stuff which can be paralleled easily, namely 1. the calculation of a value.
If we just add dummy zeros in the container, at first, we are allowed to modify the elements in the container i.e. std::vector, since we don't modify the container it self, like count or order, only its members.
So after that you can calculate in parallel, but why not directly use the new parallel algorithms to do that for us? So I added a second solution.
Also this discovery that your work consists of work which can not be paralleled and work which can, can be found in Amdahl's law.
#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>
#include <execution>
#include <future>
//Your modified solution
void updateList(std::vector<int> &list, int value){
const auto index = value;
//Do the heavy stuff here
list[index] = value;
}
int main(){
std::vector<int> list(10);
std::vector<std::future<void>> asyncTasks;
for(int i = 0; i < 10; i ++){
asyncTasks.emplace_back(std::async(std::launch::async, &updateList, std::ref(list), i));
}
for(auto &f : asyncTasks){
f.get();
}
std::for_each(list.begin(),list.end(), [](auto v) {std::cout << v << " ";});
std::cout << "\n";
}
//Better solution:
int heavy_work_calculation(int input) {
//Do the heavy stuff here
return input;
}
int main(){
std::vector<int> list(10);
std::iota(list.begin(), list.end(), 0);
std::transform(std::execution::par_unseq, list.begin(), list.end(),
list.begin(), heavy_work_calculation);
std::for_each(list.begin(),list.end(), [](auto v) {std::cout << v << " ";});
std::cout << "\n";
}

How to get indices of a Mat with specific value?

I want to find indices of an array that equal with specific value. so i've Written this code:
vector<int> _classes = { 2,2,1,1,3,3,3,3,5,5,4,4,5,6,6 };
vector<int> labelVec = {1,2,3,4,5,6};
vector<int> index;
for (int i = 0; i < labelVec.size(); i++)
{
compare(_classes, labelVec[i], index, CMP_EQ);
std::vector<int>::iterator nn = find(index.begin(), index.end(), 255);
}
but i have this error : Unhandled exception at 0x760B5608 in compareFuncTest.exe: Microsoft C++ exception: cv::Exception at memory location 0x004DDC44. if i define index as Mat, this problem will be resolved. but if i define index as Mat, i can't use from find(). also in this documentation states: output array (in my code as index) that has the same size and type as the input arrays. PLZ help me to fix this code.
I still do not get what is the point of this test, I guess this will be in some other algorithm... So, I give you two possible solutions.
1) Without OpenCV
First, you must know that
std::vector<int>::iterator nn = find(index.begin(), index.end(), 255);
Will only give you the first occurrance. Knowing this, here is a way you could check if the label is inside the _classes vector.
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> _classes = { 2,2,1,1,3,3,3,3,5,5,4,4,5,6,6 };
std::vector<int> labelVec = {1,2,3,4,5,6,7};
for (const auto& label: labelVec)
{
std::vector<int>::iterator nn = find(_classes.begin(), _classes.end(), label);
if (nn != _classes.end())
{
std::cout << "I got the value from _classes: " << *nn << std::endl;
} else
{
std::cout << "I couldn't find the value with label:" << label << std::endl;
}
}
}
Here I iterate over all the labels (as you did) and then use the find directly in the classes, but with the label variable. Then I check if I found the label or not, if not, it will give you a value equal to _classes.end() which will give error if you try to use it (look at the extra label 7 which is not found).
This example can be tested here online.
2) With OpenCV
no oline test here. But this one is also easy to do. If you have a Mat in index you will only need to change the iterators to be templated. Like this:
auto nn = find(index.begin<int>(), index.end<int>(), 255);
If you a cv::Mat of classes you can also do it as in the method before and skip the comparison part (this would be faster)
Update
Since you want is the indices and all of them, then you have to iterate over it :/ if you wanted the values you could have used copy_if. You can create a lambda function to easily do the job.
like this:
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
auto getIndices = [](const std::vector<int>& vec, const int value){
std::vector<int> result;
for (size_t t = 0; t < vec.size(); t++)
{
if (vec[t] == value)
{
result.push_back(static_cast<int>(t));
}
}
return result;
};
std::vector<int> _classes = { 2,2,1,1,3,3,3,3,5,5,4,4,5,6,6 };
std::vector<int> labelVec = {1,2,3,4,5,6,7};
for (const auto& label: labelVec)
{
std::vector<int> nn = getIndices(_classes, label);
std::cout << "I got the following indices for value"<< label<< ": [ ";
for (const auto& n : nn)
{
std::cout << n << ",";
}
std::cout << " ]" << std::endl;
}
}

How to find the index of current object in range-based for loop?

Assume I have the following code:
vector<int> list;
for(auto& elem:list) {
int i = elem;
}
Can I find the position of elem in the vector without maintaining a separate iterator?
Yes you can, it just take some massaging ;)
The trick is to use composition: instead of iterating over the container directly, you "zip" it with an index along the way.
Specialized zipper code:
template <typename T>
struct iterator_extractor { typedef typename T::iterator type; };
template <typename T>
struct iterator_extractor<T const> { typedef typename T::const_iterator type; };
template <typename T>
class Indexer {
public:
class iterator {
typedef typename iterator_extractor<T>::type inner_iterator;
typedef typename std::iterator_traits<inner_iterator>::reference inner_reference;
public:
typedef std::pair<size_t, inner_reference> reference;
iterator(inner_iterator it): _pos(0), _it(it) {}
reference operator*() const { return reference(_pos, *_it); }
iterator& operator++() { ++_pos; ++_it; return *this; }
iterator operator++(int) { iterator tmp(*this); ++*this; return tmp; }
bool operator==(iterator const& it) const { return _it == it._it; }
bool operator!=(iterator const& it) const { return !(*this == it); }
private:
size_t _pos;
inner_iterator _it;
};
Indexer(T& t): _container(t) {}
iterator begin() const { return iterator(_container.begin()); }
iterator end() const { return iterator(_container.end()); }
private:
T& _container;
}; // class Indexer
template <typename T>
Indexer<T> index(T& t) { return Indexer<T>(t); }
And using it:
#include <iostream>
#include <iterator>
#include <limits>
#include <vector>
// Zipper code here
int main() {
std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9};
for (auto p: index(v)) {
std::cout << p.first << ": " << p.second << "\n";
}
}
You can see it at ideone, though it lacks the for-range loop support so it's less pretty.
EDIT:
Just remembered that I should check Boost.Range more often. Unfortunately no zip range, but I did found a pearl: boost::adaptors::indexed. However it requires access to the iterator to pull of the index. Shame :x
Otherwise with the counting_range and a generic zip I am sure it could be possible to do something interesting...
In the ideal world I would imagine:
int main() {
std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9};
for (auto tuple: zip(iota(0), v)) {
std::cout << tuple.at<0>() << ": " << tuple.at<1>() << "\n";
}
}
With zip automatically creating a view as a range of tuples of references and iota(0) simply creating a "false" range that starts from 0 and just counts toward infinity (or well, the maximum of its type...).
jrok is right : range-based for loops are not designed for that purpose.
However, in your case it is possible to compute it using pointer arithmetic since vector stores its elements contiguously (*)
vector<int> list;
for(auto& elem:list) {
int i = elem;
int pos = &elem-&list[0]; // pos contains the position in the vector
// also a &-operator overload proof alternative (thanks to ildjarn) :
// int pos = addressof(elem)-addressof(list[0]);
}
But this is clearly a bad practice since it obfuscates the code & makes it more fragile (it easily breaks if someone changes the container type, overload the & operator or replace 'auto&' by 'auto'. good luck to debug that!)
NOTE: Contiguity is guaranteed for vector in C++03, and array and string in C++11 standard.
No, you can't (at least, not without effort). If you need the position of an element, you shouldn't use range-based for. Remember that it's just a convenience tool for the most common case: execute some code for each element. In the less-common circumstances where you need the position of the element, you have to use the less-convenient regular for loop.
Based on the answer from #Matthieu there is a very elegant solution using the mentioned boost::adaptors::indexed:
std::vector<std::string> strings{10, "Hello"};
int main(){
strings[5] = "World";
for(auto const& el: strings| boost::adaptors::indexed(0))
std::cout << el.index() << ": " << el.value() << std::endl;
}
You can try it
This works pretty much like the "ideal world solution" mentioned, has pretty syntax and is concise. Note that the type of el in this case is something like boost::foobar<const std::string&, int>, so it handles the reference there and no copying is performed. It is even incredibly efficient: https://godbolt.org/g/e4LMnJ (The code is equivalent to keeping an own counter variable which is as good as it gets)
For completeness the alternatives:
size_t i = 0;
for(auto const& el: strings) {
std::cout << i << ": " << el << std::endl;
++i;
}
Or using the contiguous property of a vector:
for(auto const& el: strings) {
size_t i = &el - &strings.front();
std::cout << i << ": " << el << std::endl;
}
The first generates the same code as the boost adapter version (optimal) and the last is 1 instruction longer: https://godbolt.org/g/nEG8f9
Note: If you only want to know, if you have the last element you can use:
for(auto const& el: strings) {
bool isLast = &el == &strings.back();
std::cout << isLast << ": " << el << std::endl;
}
This works for every standard container but auto&/auto const& must be used (same as above) but that is recommended anyway. Depending on the input this might also be pretty fast (especially when the compiler knows the size of your vector)
Replace the &foo by std::addressof(foo) to be on the safe side for generic code.
If you have a compiler with C++14 support you can do it in a functional style:
#include <iostream>
#include <string>
#include <vector>
#include <functional>
template<typename T>
void for_enum(T& container, std::function<void(int, typename T::value_type&)> op)
{
int idx = 0;
for(auto& value : container)
op(idx++, value);
}
int main()
{
std::vector<std::string> sv {"hi", "there"};
for_enum(sv, [](auto i, auto v) {
std::cout << i << " " << v << std::endl;
});
}
Works with clang 3.4 and gcc 4.9 (not with 4.8); for both need to set -std=c++1y. The reason you need c++14 is because of the auto parameters in the lambda function.
If you insist on using range based for, and to know index, it is pretty trivial to maintain index as shown below.
I do not think there is a cleaner / simpler solution for range based for loops. But really why not use a standard for(;;)? That probably would make your intent and code the clearest.
vector<int> list;
int idx = 0;
for(auto& elem:list) {
int i = elem;
//TODO whatever made you want the idx
++idx;
}
There is a surprisingly simple way to do this
vector<int> list;
for(auto& elem:list) {
int i = (&elem-&*(list.begin()));
}
where i will be your required index.
This takes advantage of the fact that C++ vectors are always contiguous.
Here's a quite beautiful solution using c++20:
#include <array>
#include <iostream>
#include <ranges>
template<typename T>
struct EnumeratedElement {
std::size_t index;
T& element;
};
auto enumerate(std::ranges::range auto& range)
-> std::ranges::view auto
{
return range | std::views::transform(
[i = std::size_t{}](auto& element) mutable {
return EnumeratedElement{i++, element};
}
);
}
auto main() -> int {
auto const elements = std::array{3, 1, 4, 1, 5, 9, 2};
for (auto const [index, element] : enumerate(elements)) {
std::cout << "Element " << index << ": " << element << '\n';
}
}
The major features used here are c++20 ranges, c++20 concepts, c++11 mutable lambdas, c++14 lambda capture initializers, and c++17 structured bindings. Refer to cppreference.com for information on any of these topics.
Note that element in the structured binding is in fact a reference and not a copy of the element (not that it matters here). This is because any qualifiers around the auto only affect a temporary object that the fields are extracted from, and not the fields themselves.
The generated code is identical to the code generated by this (at least by gcc 10.2):
#include <array>
#include <iostream>
#include <ranges>
auto main() -> int {
auto const elements = std::array{3, 1, 4, 1, 5, 9, 2};
for (auto index = std::size_t{}; auto& element : elements) {
std::cout << "Element " << index << ": " << element << '\n';
index++;
}
}
Proof: https://godbolt.org/z/a5bfxz
I read from your comments that one reason you want to know the index is to know if the element is the first/last in the sequence. If so, you can do
for(auto& elem:list) {
// loop code ...
if(&elem == &*std::begin(list)){ ... special code for first element ... }
if(&elem == &*std::prev(std::end(list))){ ... special code for last element ... }
// if(&elem == &*std::rbegin(list)){... (C++14 only) special code for last element ...}
// loop code ...
}
EDIT: For example, this prints a container skipping a separator in the last element. Works for most containers I can imagine (including arrays), (online demo http://coliru.stacked-crooked.com/a/9bdce059abd87f91):
#include <iostream>
#include <vector>
#include <list>
#include <set>
using namespace std;
template<class Container>
void print(Container const& c){
for(auto& x:c){
std::cout << x;
if(&x != &*std::prev(std::end(c))) std::cout << ", "; // special code for last element
}
std::cout << std::endl;
}
int main() {
std::vector<double> v{1.,2.,3.};
print(v); // prints 1,2,3
std::list<double> l{1.,2.,3.};
print(l); // prints 1,2,3
std::initializer_list<double> i{1.,2.,3.};
print(i); // prints 1,2,3
std::set<double> s{1.,2.,3.};
print(s); // print 1,2,3
double a[3] = {1.,2.,3.}; // works for C-arrays as well
print(a); // print 1,2,3
}
Tobias Widlund wrote a nice MIT licensed Python style header only enumerate (C++17 though):
GitHub
Blog Post
Really nice to use:
std::vector<int> my_vector {1,3,3,7};
for(auto [i, my_element] : en::enumerate(my_vector))
{
// do stuff
}
If you want to avoid having to write an auxiliary function while having
the index variable local to the loop, you can use a lambda with a mutable variable.:
int main() {
std::vector<char> values = {'a', 'b', 'c'};
std::for_each(begin(values), end(values), [i = size_t{}] (auto x) mutable {
std::cout << i << ' ' << x << '\n';
++i;
});
}
Here's a macro-based solution that probably beats most others on simplicity, compile time, and code generation quality:
#include <iostream>
#define fori(i, ...) if(size_t i = -1) for(__VA_ARGS__) if(i++, true)
int main() {
fori(i, auto const & x : {"hello", "world", "!"}) {
std::cout << i << " " << x << std::endl;
}
}
Result:
$ g++ -o enumerate enumerate.cpp -std=c++11 && ./enumerate
0 hello
1 world
2 !

Calling a function on every element of a C++ vector

In C++, is there a way to call a function on each element of a vector, without using a loop running over all vector elements? Something similar to a 'map' in Python.
You've already gotten several answers mentioning std::for_each.
While these respond to the question you've asked, I'd add that at least in my experience, std::for_each is about the least useful of the standard algorithms.
I use (for one example) std::transform, which is basically a[i] = f(b[i]); or result[i] = f(a[i], b[i]); much more frequently than std::for_each. Many people frequently use std::for_each to print elements of a collection; for that purpose, std::copy with an std::ostream_iterator as the destination works much better.
Yes: std::for_each.
#include <algorithm> //std::for_each
void foo(int a) {
std::cout << a << "\n";
}
std::vector<int> v;
...
std::for_each(v.begin(), v.end(), &foo);
On C++ 11: You could use a lambda. For example:
std::vector<int> nums{3, 4, 2, 9, 15, 267};
std::for_each(nums.begin(), nums.end(), [](int &n){ n++; });
ref: http://en.cppreference.com/w/cpp/algorithm/for_each
If you have C++11, there's an even shorter method: ranged-based for. Its purpose is exactly this.
std::vector<int> v {1,2,3,4,5};
for (int element : v)
std::cout << element; //prints 12345
You can also apply references and const to it as well, when appropriate, or use auto when the type is long.
std::vector<std::vector<int>> v {{1,2,3},{4,5,6}};
for (const auto &vec : v)
{
for (int element : vec)
cout << element;
cout << '\n';
}
Output:
123
456
The OP mentions the map function in Python.
This Python function actually applies a function to every element of a list (or iterable) and returns a list (or iterable) that collects all results.
In other words, it does something like this:
def f( x ) :
""" a function that computes something with x"""
# code here
return y
input = [ x1, x2, x3, ... ]
output = map( func, input )
# output is now [ f(x1), f(x2), f(x3), ...]
Hence, the closest C++ standard-library equivalent to Python's map is actually std::transform (from the <algorithm> header).
Example usage is as follows:
#include <vector>
#include <algorithm>
using namespace std;
double f( int x ) {
// a function that computes the square of x divided by 2.0
return x * x / 2.0 ;
}
int main( ) {
vector<int> input{ 1, 5, 10 , 20};
vector<double> output;
output.resize( input.size() ); // unfortunately this is necessary
std::transform( input.begin(), input.end(), output.begin(), f );
// output now contains { f(1), f(5), f(10), f(20) }
// = { 0.5, 12.5, 50.0, 200.0 }
return 0;
}
Use for_each:
// for_each example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void myfunction (int i) {
cout << " " << i;
}
struct myclass {
void operator() (int i) {cout << " " << i;}
} myobject;
int main () {
vector<int> myvector;
myvector.push_back(10);
myvector.push_back(20);
myvector.push_back(30);
cout << "myvector contains:";
for_each (myvector.begin(), myvector.end(), myfunction);
// or:
cout << "\nmyvector contains:";
for_each (myvector.begin(), myvector.end(), myobject);
cout << endl;
return 0;
}
You can use std::for_each which takes a pair of iterators and a function or functor.
Thought I would share std::ranges equivalents for for_each and transform, should anyone prefer them:
std::vector<int> v;
std::ranges::for_each(v,[](const auto& n) {});
const auto squared = v | std::views::transform([](const auto& n) { return n*2; });
Running on godbolt: https://godbolt.org/z/zYME6b

Printing an array in C++?

Is there a way of printing arrays in C++?
I'm trying to make a function that reverses a user-input array and then prints it out. I tried Googling this problem and it seemed like C++ can't print arrays. That can't be true can it?
Just iterate over the elements. Like this:
for (int i = numElements - 1; i >= 0; i--)
cout << array[i];
Note: As Maxim Egorushkin pointed out, this could overflow. See his comment below for a better solution.
Use the STL
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <ranges>
int main()
{
std::vector<int> userInput;
// Read until end of input.
// Hit control D
std::copy(std::istream_iterator<int>(std::cin),
std::istream_iterator<int>(),
std::back_inserter(userInput)
);
// ITs 2021 now move this up as probably the best way to do it.
// Range based for is now "probably" the best alternative C++20
// As we have all the range based extension being added to the language
for(auto const& value: userInput)
{
std::cout << value << ",";
}
std::cout << "\n";
// Print the array in reverse using the range based stuff
for(auto const& value: userInput | std::views::reverse)
{
std::cout << value << ",";
}
std::cout << "\n";
// Print in Normal order
std::copy(userInput.begin(),
userInput.end(),
std::ostream_iterator<int>(std::cout,",")
);
std::cout << "\n";
// Print in reverse order:
std::copy(userInput.rbegin(),
userInput.rend(),
std::ostream_iterator<int>(std::cout,",")
);
std::cout << "\n";
}
May I suggest using the fish bone operator?
for (auto x = std::end(a); x != std::begin(a); )
{
std::cout <<*--x<< ' ';
}
(Can you spot it?)
Besides the for-loop based solutions, you can also use an ostream_iterator<>. Here's an example that leverages the sample code in the (now retired) SGI STL reference:
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
short foo[] = { 1, 3, 5, 7 };
using namespace std;
copy(foo,
foo + sizeof(foo) / sizeof(foo[0]),
ostream_iterator<short>(cout, "\n"));
}
This generates the following:
./a.out
1
3
5
7
However, this may be overkill for your needs. A straight for-loop is probably all that you need, although litb's template sugar is quite nice, too.
Edit: Forgot the "printing in reverse" requirement. Here's one way to do it:
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
short foo[] = { 1, 3, 5, 7 };
using namespace std;
reverse_iterator<short *> begin(foo + sizeof(foo) / sizeof(foo[0]));
reverse_iterator<short *> end(foo);
copy(begin,
end,
ostream_iterator<short>(cout, "\n"));
}
and the output:
$ ./a.out
7
5
3
1
Edit: C++14 update that simplifies the above code snippets using array iterator functions like std::begin() and std::rbegin():
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
short foo[] = { 1, 3, 5, 7 };
// Generate array iterators using C++14 std::{r}begin()
// and std::{r}end().
// Forward
std::copy(std::begin(foo),
std::end(foo),
std::ostream_iterator<short>(std::cout, "\n"));
// Reverse
std::copy(std::rbegin(foo),
std::rend(foo),
std::ostream_iterator<short>(std::cout, "\n"));
}
There are declared arrays and arrays that are not declared, but otherwise created, particularly using new:
int *p = new int[3];
That array with 3 elements is created dynamically (and that 3 could have been calculated at runtime, too), and a pointer to it which has the size erased from its type is assigned to p. You cannot get the size anymore to print that array. A function that only receives the pointer to it can thus not print that array.
Printing declared arrays is easy. You can use sizeof to get their size and pass that size along to the function including a pointer to that array's elements. But you can also create a template that accepts the array, and deduces its size from its declared type:
template<typename Type, int Size>
void print(Type const(& array)[Size]) {
for(int i=0; i<Size; i++)
std::cout << array[i] << std::endl;
}
The problem with this is that it won't accept pointers (obviously). The easiest solution, I think, is to use std::vector. It is a dynamic, resizable "array" (with the semantics you would expect from a real one), which has a size member function:
void print(std::vector<int> const &v) {
std::vector<int>::size_type i;
for(i = 0; i<v.size(); i++)
std::cout << v[i] << std::endl;
}
You can, of course, also make this a template to accept vectors of other types.
Most of the libraries commonly used in C++ can't print arrays, per se. You'll have to loop through it manually and print out each value.
Printing arrays and dumping many different kinds of objects is a feature of higher level languages.
It certainly is! You'll have to loop through the array and print out each item individually.
This might help
//Printing The Array
for (int i = 0; i < n; i++)
{cout << numbers[i];}
n is the size of the array
std::string ss[] = { "qwerty", "asdfg", "zxcvb" };
for ( auto el : ss ) std::cout << el << '\n';
Works basically like foreach.
My simple answer is:
#include <iostream>
using namespace std;
int main()
{
int data[]{ 1, 2, 7 };
for (int i = sizeof(data) / sizeof(data[0])-1; i >= 0; i--) {
cout << data[i];
}
return 0;
}
You can use reverse iterators to print an array in reverse:
#include <iostream>
int main() {
int x[] = {1,2,3,4,5};
for (auto it = std::rbegin(x); it != std::rend(x); ++it)
std::cout << *it;
}
output
54321
If you already reversed the array, you can replace std::rbegin and std::rend with std::begin/std::end, respectively, to iterate the array in forward direction.
It's quite straightforward to copy the array's elements to a suitable output iterator. For example (using C++20 for the Ranges version):
#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
template<typename T, std::size_t N>
std::ostream& print_array(std::ostream& os, std::array<T,N> const& arr)
{
std::ranges::copy(arr, std::ostream_iterator<T>(os, ", "));
return os;
}
Quick demo:
int main()
{
std::array example{ "zero", "one", "two", "three", };
print_array(std::cout, example) << '\n';
}
Of course it's more useful if we can output any kind of collection, not only arrays:
#include <algorithm>
#include <iterator>
#include <iosfwd>
#include <ranges>
template<std::ranges::input_range R>
std::ostream& print_array(std::ostream& os, R const& arr)
{
using T = std::ranges::range_value_t<R>;
std::ranges::copy(arr, std::ostream_iterator<T>(os, ", "));
return os;
}
The question mentions reversing the array for printing. That's easily achieved by using a view adapter:
print_array(std::cout, example | std::views::reverse) << '\n';
// Just do this, use a vector with this code and you're good lol -Daniel
#include <Windows.h>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
std::vector<const char*> arry = { "Item 0","Item 1","Item 2","Item 3" ,"Item 4","Yay we at the end of the array"};
if (arry.size() != arry.size() || arry.empty()) {
printf("what happened to the array lol\n ");
system("PAUSE");
}
for (int i = 0; i < arry.size(); i++)
{
if (arry.max_size() == true) {
cout << "Max size of array reached!";
}
cout << "Array Value " << i << " = " << arry.at(i) << endl;
}
}
If you want to make a function that prints every single element in an array;
#include <iostream>
using namespace std;
int myArray[] = {1,2,3,4, 77, 88};
void coutArr(int *arr, int size){
for(int i=0; i<size/4; i++){
cout << arr[i] << endl;
}
}
int main(){
coutArr(myArray, sizeof(myArray));
}
The function above prints every single element in an array only, not commas etc.
You may be wondering "Why sizeoff(arr) divided by 4?". It's because cpp prints 4 if there's only a single element in an array.