[c++] Correct way of looping through C++ arrays

Recently I have found a lot of examples, most of them regards the C++ 98, anyways I have created my simple-array and a loop (codepad):

#include <iostream>
using namespace std;

int main ()
{
   string texts[] = {"Apple", "Banana", "Orange"};
   for( unsigned int a = 0; a < sizeof(texts); a = a + 1 )
   {
       cout << "value of a: " << texts[a] << endl;
   }

   return 0;
}

Output:

value of a: Apple
value of a: Banana
value of a: Orange

Segmentation fault

It's working fine, except the segmentation fault at the end.

My question is, does this array/loop through is done a good way? I am using C++ 11 so would like to be sure it fits the standards and couldnt be done a better way?

This question is related to c++ arrays loops c++11

The answer is


You can do it as follow:

#include < iostream >

using namespace std;

int main () {

   string texts[] = {"Apple", "Banana", "Orange"};

   for( unsigned int a = 0; a < sizeof(texts) / 32; a++ ) { // 32 is the size of string data type

       cout << "value of a: " << texts[a] << endl;

   }


   return 0;

}

Add a stopping value to the array:

#include <iostream>
using namespace std;

int main ()
{
   string texts[] = {"Apple", "Banana", "Orange", ""};
   for( unsigned int a = 0; texts[a].length(); a = a + 1 )
   {
       cout << "value of a: " << texts[a] << endl;
   }

   return 0;
}

string texts[] = {"Apple", "Banana", "Orange"};
for( unsigned int a = 0; a < sizeof(texts); a = a + 1 )
{
    cout << "value of a: " << texts[a] << endl;
}

Nope. Totally a wrong way of iterating through an array. sizeof(texts) is not equal to the number of elements in the array!

The modern, C++11 ways would be to:

  • use std::array if you want an array whose size is known at compile-time; or
  • use std::vector if its size depends on runtime

Then use range-for when iterating.

#include <iostream>
#include <array>


int main() {
    std::array<std::string, 3> texts = {"Apple", "Banana", "Orange"};
    // ^ An array of 3 elements with the type std::string

    for(const auto& text : texts) {   // Range-for!
        std::cout << text << std::endl;
    }
}

Live example


You may ask, how is std::array better than the ol' C array? The answer is that it has the additional safety and features of other standard library containers, mostly closely resembling std::vector. Further, The answer is that it doesn't have the quirks of decaying to pointers and thus losing type information, which, once you lose the original array type, you can't use range-for or std::begin/end on it.


you need to understand difference between std::array::size and sizeof() operator. if you want loop to array elements in conventional way then you could use std::array::size. this will return number of elements in array but if you keen to use C++11 then prefer below code

for(const string &text : texts)
    cout << "value of text: " << text << endl;

sizeof(texts) on my system evaluated to 96: the number of bytes required for the array and its string instances.

As mentioned elsewhere, the sizeof(texts)/sizeof(texts[0]) would give the value of 3 you were expecting.


How about:

#include <iostream>
#include <array>
#include <algorithm>

int main ()
{
    std::array<std::string, 3> text = {"Apple", "Banana", "Orange"};
    std::for_each(text.begin(), text.end(), [](std::string &string){ std::cout << string << "\n"; });

    return 0;
}

Compiles and works with C++ 11 and has no 'raw' looping :)


If you have a very short list of elements you would like to handle, you could use the std::initializer_list introduced in C++11 together with auto:

#include <iostream>

int main(int, char*[])
{
    for(const auto& ext : { ".slice", ".socket", ".service", ".target" })
        std::cout << "Handling *" << ext << " systemd files" << std::endl;

    return 0;
}

sizeof tells you the size of a thing, not the number of elements in it. A more C++11 way to do what you are doing would be:

#include <array>
#include <string>
#include <iostream>

int main()
{
    std::array<std::string, 3> texts { "Apple", "Banana", "Orange" };
    for (auto& text : texts) {
        std::cout << text << '\n';
    }
    return 0;
}

ideone demo: http://ideone.com/6xmSrn


Examples related to c++

Method Call Chaining; returning a pointer vs a reference? How can I tell if an algorithm is efficient? Difference between opening a file in binary vs text How can compare-and-swap be used for a wait-free mutual exclusion for any shared data structure? Install Qt on Ubuntu #include errors detected in vscode Cannot open include file: 'stdio.h' - Visual Studio Community 2017 - C++ Error How to fix the error "Windows SDK version 8.1" was not found? Visual Studio 2017 errors on standard headers How do I check if a Key is pressed on C++

Examples related to arrays

PHP array value passes to next row Use NSInteger as array index How do I show a message in the foreach loop? Objects are not valid as a React child. If you meant to render a collection of children, use an array instead Iterating over arrays in Python 3 Best way to "push" into C# array Sort Array of object by object field in Angular 6 Checking for duplicate strings in JavaScript array what does numpy ndarray shape do? How to round a numpy array?

Examples related to loops

How to increment a letter N times per iteration and store in an array? Angular 2 Cannot find control with unspecified name attribute on formArrays What is the difference between i = i + 1 and i += 1 in a 'for' loop? Prime numbers between 1 to 100 in C Programming Language Python Loop: List Index Out of Range JavaScript: Difference between .forEach() and .map() Why does using from __future__ import print_function breaks Python2-style print? Creating an array from a text file in Bash Iterate through dictionary values? C# Wait until condition is true

Examples related to c++11

Remove from the beginning of std::vector Converting std::__cxx11::string to std::string What exactly is std::atomic? C++ How do I convert a std::chrono::time_point to long and back Passing capturing lambda as function pointer undefined reference to 'std::cout' Is it possible to use std::string in a constexpr? How does #include <bits/stdc++.h> work in C++? error::make_unique is not a member of ‘std’ no match for ‘operator<<’ in ‘std::operator