Reputation: 3715
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?
Upvotes: 95
Views: 371461
Reputation: 312
The sizeof function returns the size of string in bits that the system is using, either. So if you have an array of string with three items, the sizeof will return (3 x bits used by system to store a string). Dividing the sizeof(array) by the sizeof(array[0] will give the what we, in general, call the length of the array.
You can do it as follows (NOTE: This is tested in c and should work in c++):
#include <iostream>
using namespace std;
int main () {
string texts[] = {"Apple", "Banana", "Orange"};
for ( unsigned int a = 0; a < (sizeof(texts) / sizeof(texts[0])); a++ ) // sizeof(texts) / sizeof(text[0]) is the length of array texts, number of items that array can hold.
{
cout << "value of a: " << texts[a] << endl;
}
return 0;
}
Upvotes: -2
Reputation: 2043
Feels like its illegal but this works:
So basically it is dynamic multidimensional array iteration termination case and it differs a bit from one dimensional solution, last element is -1 and it is stop value for cycle (I am new to C++ but this method me likes)
int arr[][3] = {{164, 0, 0}, {124, 0, 0}, {92, 4, 0}, {68, 4, 0}, -1};
for(int i = 0; arr[i][0]!=-1; i++)
{
cout << i << "\n";
}
Upvotes: -2
Reputation: 39
In my point of view: It is because the sizeof() operator returns the size of a type in bytes. So, Simply we can use size() instead of sizeof(). If we need or must use sizeof() we have to divide it with sizeof(dataType):
First way:
#include <iostream>
using namespace std;
int main ()
{
string texts[] = {"Apple", "Banana", "Orange"};
for (int a = 0; a < size(texts); a++)
{
cout << "value of a: " << texts[a] << endl;
}
return 0;
}
Second way:
#include <iostream>
using namespace std;
int main ()
{
string texts[] = {"Apple", "Banana", "Orange"};
for (int a=0; a<sizeof(texts)/sizeof(string); a++)
{
cout << "value of a: " << texts[a] << endl;
}
return 0;
}
Upvotes: 1
Reputation: 8687
In C/C++ sizeof
. always gives the number of bytes in the entire object, and arrays are treated as one object. Note: sizeof
a pointer--to the first element of an array or to a single object--gives the size of the pointer, not the object(s) pointed to. Either way, sizeof
does not give the number of elements in the array (its length). To get the length, you need to divide by the size of each element. eg.,
for( unsigned int a = 0; a < sizeof(texts)/sizeof(texts[0]); a = a + 1 )
As for doing it the C++11 way, the best way to do it is probably
for(const string &text : texts)
cout << "value of text: " << text << endl;
This lets the compiler figure out how many iterations you need.
as others have pointed out, std::array
is preferred in C++11 over raw arrays; however, none of the other answers addressed why sizeof
is failing the way it is, so I still think this is the better answer.
Upvotes: 135
Reputation: 41
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;
Upvotes: 4
Reputation: 51
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 :)
Upvotes: 2
Reputation: 2271
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;
}
Upvotes: 2
Reputation: 2166
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;
}
Upvotes: 0
Reputation: 3392
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.
Upvotes: 2
Reputation: 17708
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:
std::array
if you want an array whose size is known at compile-time; orstd::vector
if its size depends on runtimeThen 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;
}
}
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.
Upvotes: 34
Reputation: 24259
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
Upvotes: 16