'Iterate elements of array using pointer

I try execute code:

char* m[3] = {"123", "456", "789"};
for(char* st=*m; st!=0; st=*(m+1))
{
    cout <<st;
} 

but it hung up and print: 123456456456...



Solution 1:[1]

Stop using char* for strings immediately and start using std::string. The same goes for C-style arrays: start using std::array or std::vector. This will save you years of your life and unnecessary pain.

Just look at how beautiful this code is:

std::array<std::string, 3> m = {"123", "456", "789"};
for (auto& s : m) 
    std::cout << s;

and here's the live example.

Solution 2:[2]

Using the code you provided here is one way of doing it:

const char* m[3]={"123","456","789"};
const unsigned int element_count = sizeof(m) / sizeof(m[0]);
//not a nice to have sizeof here, but i used this to keep the code
// consistent with the code provided in the question

for( const char** st = m; st!= (m + element_count) ; st ++ )
{
    cout << *st;
}

As you can see to iterate trough an array of char* elements you need to use a pointer to char* and therefore the type is char ** for the iteration variable st.

The code you has was an infinite loop because you assigned st with *(m+1) which is never equal to 0, in fact it's the second element every time.

However there are safer ways of using doing this, by using a std::vector for example:

std::vector<std::string> m = {"123", "456", "789"};
for (auto& st : m) 
    std::cout << st;
//or:
for(std::vector<std::string>::iterator i = m.begin(),e = m.end();i != e;i++)
    std::cout << *i;
//or:
for(std::size_t i = 0;i < m.size() ;i++)
    std::cout << m[i];

Solution 3:[3]

The problem is that you point a pointer to the same location in each iteration:

char* m[ 3]={ "123","456","789"};
for( char* st = *m; st != 0; st = *( m + 1))
                               // ^^^^^^^^^  <- this doesn't change, 
                               //               st points to *(m+1)
{
    std::cout << st;
}

Also you should not use a non-const char * to point to a nonmodifiable string literal:

const char* m[ 3]={ "123","456","789"};
const unsigned int n = sizeof( m) / sizeof( m[ 0]);

for( const char** st = m; st != (m + n) ; st ++ )
{
    cout << *st;
}

Even range - based iteration will work:

const char* m[ 3] = { "123", "456", "789" };
for ( const char* st : m )
{
    std::cout << st << std::endl;
} 

If for some reason you have to stick to simple iteration, this will also work:

const char* m[ 3]={ "123","456","789"};
const char* st;
int r = 0;
for( st = *m; r < 3; st = *( m+r))
{
    std::cout << st << std::endl;
    r++;
}

Please consider using a standard container, i.e std::vector or std::array. It will help you a lot, mainly in dynamic memory management.

std::vector< std::string> v = { "123", "456", "789"};
for ( auto& s : v) 
    std::cout << s;

Solution 4:[4]

This is the least intrusive solution:

char* m[4] = {"123", "456", "789", NULL};
for(char** st=m; *st!=0; st=(st+1))
{
    cout <<*st;
} 

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Shoe
Solution 2
Solution 3
Solution 4 Smiley1000