1

I needed to be able to display the contents of my various arrays (for debugging purposes at this point), and decided to write a function to help me with that. This is what I came up with. The goal is to be able to display any type of incoming array (int, double, etc). Because I never had any official programming training, I am wondering if what I have is too "inelegant" and could be improved by doing something obvious to a good computer science person, but not so to a layperson.

int
DisplayArrayInDebugWindow(
void**              incoming_array,
char*               array_type_str,
int                 array_last_index_dim_size,
int                 array_terminator,
HWND                handle_to_display_window,
wchar_t*            optional_array_name     ) 
{

wchar_t             message_bufferw[1000];
    message_bufferw[0] =                                                        L'\0';
wchar_t             temp_buffer[400];
if ( array_last_index_dim_size == 0 ) { array_last_index_dim_size =             1; }

// ----------------------------------------------------------------------------
// Processing for "int" type array
// ----------------------------------------------------------------------------
if (    0 == (strcmp( array_type_str, "int" ))  )
{

    int             j =                                                         0;
    swprintf( temp_buffer,                                                      L"%s\r\n", optional_array_name );
    wcscat( message_bufferw,                                                    temp_buffer );
    for ( int i = 0; ((int)(*((int*)( (int)incoming_array + i * (int)sizeof(int) * array_last_index_dim_size + j * (int)sizeof(int))))) != array_terminator; i++ )
    {
        swprintf( temp_buffer, L"%02i:\t", i );
        wcscat( message_bufferw,                                                temp_buffer );
        for ( j; j < last_array_dim_size; j++ )
        {
            swprintf( temp_buffer, L"%i\t", ((int)(*((int*)( (int)incoming_array + i  * (int)sizeof(int) * array_last_index_dim_size + j * (int)sizeof(int) )))) ); //
            wcscat( message_bufferw,                                            temp_buffer );
        }   
        wcscat( message_bufferw,                                                L"\r\n" );

        // --------------------------------------------------------------------
        // reset j to 0 each time
        // --------------------------------------------------------------------
        j =                                                                     0;
    }
    swprintf( temp_buffer,                                                      L"\nEnd of Array\n" );
    wcscat( message_bufferw,                                                    temp_buffer );
    SetWindowText( handle_to_display_window, message_bufferw );
}


return 0;
}

NB: When I pass in "incoming array", I type cast it as (void**) obviously.

a1s2d3f4
  • 589
  • 4
  • 7
  • 18
  • 5
    C or C++? In C++ you can use templates to remove a lot of the complexity. – user253751 Aug 31 '15 at 03:12
  • I *really* hope that this is not meant to be C++ code. Please remove one of the tags, the two different languages call for different answers. – Baum mit Augen Aug 31 '15 at 03:14
  • 2
    Also what's with your formatting - why is it in two columns? – user253751 Aug 31 '15 at 03:18
  • 1
    If code is working, http://codereview.stackexchange.com/ may be appropriated. – Jarod42 Aug 31 '15 at 08:15
  • @BaummitAugen Thanks for pointing this out. I don't really know what the difference is-except that c is a subset of c++ and that I don't yet use things like "classes" and whatever else that c++ introduced. However, I "compile as c++", if that makes sense, and, therefore, I don't mind starting to introduce c++ ways into my code, if it makes sense, which, judging by one of the answers, it does. I am formatting with columns because after years of making my code "fit within 80 characters", I realized it's not working for me. I have 1080p display and plenty of real estate to improve my experience. – a1s2d3f4 Aug 31 '15 at 14:14
  • @Jarod42 I did not know about codereview. Yes, this code is working, but it seems exceptionally cumbersome. – a1s2d3f4 Aug 31 '15 at 14:14
  • @a1s2d3f4 "c is a subset of c++" Not even this holds, you cannot compile C code as C++ in general (`restrict`, different type conversion rules, etc.). C and C++ are two different languages, and most C code that compiles as C++ is still horrible C++, even if it happens to be correct. For example, the `malloc` family is quite a dangerous class of functions in C++. – Baum mit Augen Aug 31 '15 at 14:20
  • @BaummitAugen You are scaring me, because my program has plenty of mallocs and I was hoping that it would be a smooth transition to eventually start using c++ constructs as I discover their usefulness for my code. As a self-trained programmer I really appreciate any explanations (or pointers) as to why things should be done one way and not the other by those who know what they are doing. – a1s2d3f4 Aug 31 '15 at 16:24
  • @a1s2d3f4 Concerning `malloc`: Many classes in C++ must run a special member function called constructor before being useable. `malloc` does not do this -> potential source for trouble. Many people handle this with `new` and `delete`, which works, but is not modern C++ either because it violates the important RAII concept. Tbh I would not start to mix C++ and C code. Just learn C++ from a [good book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) and keep compiling your C code as C. You can later on access the C functions from your C++ translation units. – Baum mit Augen Aug 31 '15 at 18:54

1 Answers1

0

When the data type changes but the algorithm doesn't, it's time to consider using templates.

template<class Element_Type>
print_array(Element_Type const * p_begin,
            Element_Type const * p_end)
{
  while (p_begin != p_end)
  {
    cout << *p_begin;
    ++p_begin;
  }
}

The conversion from single dimension to multiple dimension is left as an exercise to the OP and readers.

Edit 1: Another alternative
At some point, the output function will need information about how to print the information you gave it.

One option is for you to write your own printf function that has format specifiers for the data you send it.

While another option is to pass a pointer to a function that prints the data.

The fundamental issue is that the output function needs to know how to print the data.

For C++, I suggest overriding operator<< in the class / structure. Since the class/structure knows the data, it can easily know how to print the data.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
  • I have not yet gotten comfortable with implementing classes and templates and all these other c++ things, but it appears that your c++ based solution is a lot simpler than what i have, suggesting it makes sense to spend some time browsing online. I'll need to figure out what Element_Type. Browsing online is not giving me anything when I search for "class Element_Type". Is p_end what I call my "array_terminator"? – a1s2d3f4 Aug 31 '15 at 14:25
  • Since C and C++ are strongly typed language, you will need to pass information about the type to the printing function; otherwise the printing function will not know how to print the data (variable) you gave it. Another option is to pass a function pointer or function object that handles the printing for the given object. – Thomas Matthews Aug 31 '15 at 15:48
  • @a1s2d3f4 `Element_Type` is just an arbitrary name chosen by Thomas. The interesting part is the `template `. But I highly recommend learning C++ systematically, not bit by bit from the internet. – Baum mit Augen Aug 31 '15 at 19:05
  • @BaummitAugen Thanks for the suggestions. To wrap up this discussion, if I were to stick with "C" (meaning no classes/templates), is there a more elegant way for this function than what I have, or is this a clear example of the advantage of C++ over C? – a1s2d3f4 Sep 01 '15 at 12:53