Search code examples
c++arrayscharpointer-to-pointer

print each char of string array with double pointer in C++


The program is expected to print each char of the string array.

#include <iostream>
#include <string>

using namespace std;
int main()
{
    const char* numbers[10]{"One", "Too",   "Three", "Four", "Five",
                "Six", "Seven", "Eight", "Nine", "Zero"};

    /*  This version did not work. Why?
           for (const char** ptr = numbers; *ptr != nullptr; *ptr++) {
                const char* pos = *ptr;
                while (*pos != '\0')
                    cout << *(pos++) << " ";
            }
    */
    for(unsigned int i = 0; i < sizeof(numbers) / sizeof(numbers[0]); ++i)
    {
        const char* pos = numbers[i];
        while(*pos != '\0')
            printf("%c ", *(pos++));
        printf("\n");
    }
    return 0;
}

I am aware that my code is a mixture of C++17 and C(in a transition from C to C++, nullptr, cout are two examples), but not sure the first for-loop with

for (const char** ptr = numbers; *ptr != nullptr; *ptr++)

is correct or not. What's wrong with it? Is there a "best practice" to looping thru array of string(char array , not string object yet), especially with the double pointer I'd like to catch, in this case? Thanks!


Solution

  • Two things -

    First, in this loop expression, you don't need to dereference the ptr after incrementing it - *ptr++.

    for (const char** ptr = numbers; *ptr != nullptr; *ptr++)
                                                      ^^
    

    *ptr++ will be grouped as - *(ptr++), which means, (post)increment the ptr and dereference the result of (post)increment. It should be just ptr++, as we need the ptr pointer to point to next element in the numbers array after executing the loop body.

    Second, if your loop condition is checking for nullptr then the array, which loop is iterating, should have nullptr as a marker to indicate the end of array and you need to increase the size of array as well to adjust end marker:

         const char* numbers[11] {"One", "Too", "Three", "Four", "Five",
                                  "Six", "Seven", "Eight", "Nine", "Zero", nullptr};
    

    With the above mentioned changes, the following loop should print the numbers array strings:

           for (const char** ptr = numbers; *ptr != nullptr; ptr++) {
               const char* pos = *ptr;
    
               while (*pos != '\0')
                   cout << *(pos++) << " ";
    
               cout << "\n";
           }
    

    Since, you have added a new element in the numbers array to mark end of array, be cautious, in the second loop, you are doing sizeof(numbers)/sizeof(numbers[0]) to get the array size and it will give 11 and second loop will end up accessing the nullptr which will be undefined behaviour. Either subtract 1 from sizeof result in loop condition or add a check pos != nullptr before processing it.