How can you print out different strings in different coordinates?

77 views Asked by At

I have to make a table and I don't want to hard code it.

COORD point = { 30, 10 };
SetConsoleCursorPosition(hConsole, point);
printf("%s", a);
COORD point1 = { 30,12 };
SetConsoleCursorPosition(hConsole, point1);
printf("%s", b);
COORD point2 = { 30,14 };
SetConsoleCursorPosition(hConsole, point2);
printf("%s", c);
COORD point3 = { 30,16 };
SetConsoleCursorPosition(hConsole, point3);
printf("%s", d);
COORD point4 = { 30,18 };
SetConsoleCursorPosition(hConsole, point4);
printf("%s", e);
COORD point5 = { 50,10 };
SetConsoleCursorPosition(hConsole, point5);
printf("%s", f);
COORD point6 = { 50,12 };
SetConsoleCursorPosition(hConsole, point6);
printf("%s", g);
COORD point7 = { 50,14 };
SetConsoleCursorPosition(hConsole, point7);
printf("%s", h);
COORD point8 = { 50,16 };
SetConsoleCursorPosition(hConsole, point8);
printf("%s", k);
COORD point9 = { 50,18 };
SetConsoleCursorPosition(hConsole, point9);
printf("%d", l);

Basically I have this and I'm interested if I can make this through for loop or something like that

2

There are 2 answers

3
Andreas Wenzel On BEST ANSWER

It is generally not a good idea to have many variables named point1 to point9, as this will not allow you to use them in a loop. However, if you instead have these variables in a single array, then you can use them in a loop.

The same applies to the variables named a to l.

This is what your code could look like if you use arrays and loops instead:

// The following array should contain the values of
// the variables "a" to "l"
char *strings[10];
// TODO: initialize the elements in the strings array
//       to the appropriate values

COORD points[10];

for ( int i = 0; i < 2; i++ )
{
    for ( int j = 0; j < 5; j++ )
    {
        points[i*5+j].X = 30 + i * 20;
        points[i*5+j].Y = 10 + j * 2;
        SetConsoleCursorPosition( hConsole, points[i*5+j] );
        printf( "%s", strings[i*5+j] );
    }
}

However, you probably don't need to remember the coordinates after having passed them to SetConsoleCursurPosition. In that case, you don't need an array of coordinates, so the code can be simplified to the following:

// The following array should contain the values of
// the variables "a" to "l"
char *strings[10];
// TODO: initialize the elements in the strings array
//       to the appropriate values

for ( int i = 0; i < 2; i++ )
{
    for ( int j = 0; j < 5; j++ )
    {
        COORD point;

        point.X = 30 + i * 20;
        point.Y = 10 + j * 2;
        SetConsoleCursorPosition( hConsole, point );
        printf( "%s", strings[i*5+j] );
    }
}

Depending on the situation, you may also prefer to use a 2D array (i.e. an array of arrays), for example like in the following code. I have changed the code to use macro constants too, because that is cleaner.

The following code should be at the start of the file, outside any function, best below the #include directives of the file:

#define NUM_COLS 2
#define NUM_ROWS 5
#define LEFT_MARGIN 30
#define COLUMN_WIDTH 20
#define TOP_MARGIN 10
#define ROW_HEIGHT 2

Then you can use for example the following code inside the function:

const char *strings[NUM_COLS][NUM_ROWS] =
{
    {
        "string for first column, first row",
        "string for first column, second row",
        "string for first column, third row",
        "string for first column, fourth row",
        "string for first column, fifth row"
    },

    {
        "string for second column, first row",
        "string for second column, second row",
        "string for second column, third row",
        "string for second column, fourth row",
        "string for second column, fifth row"
    }
};

for ( int i = 0; i < NUM_COLS; i++ )
{
    for ( int j = 0; j < NUM_ROWS; j++ )
    {
        COORD point;

        point.X = LEFT_MARGIN + i * COLUMN_WIDTH;
        point.Y =  TOP_MARGIN + j * ROW_HEIGHT;
        SetConsoleCursorPosition( hConsole, point );
        printf( "%s", strings[i][j] );
    }
}

Note that the placeholder strings should be changed to be made shorter, because they won't actually fit in the column, because in your example, the column only has room for 20 characters.

The code above assumes that the COORD structure that you are using is this one from the Windows API.

In the comments section, you stated that the variables a to l did not all have the same type. You stated that one of the variables had a different type. In that case, the situation is more complicated, and it would probably be better to handle the variable with a different type outside the loop, or to maybe convert that variable to a string before the loop, so that they can all be handled the same way.

2
greg spears On

It's a little tricky because not every element lends itself nicely to a loop, but per code below, it is doable. Tricky because halfway through the printing, the X Coord jumps from 30 to 50. We account for that in the code, but it does tend to break the linearity of an ideal loop.

Also, the strings to be printed are relegated to a 2 dimensional array. This really assists linearity of the loop nicely, and I have used this practically a lot. So, this isn't one-off code, but reusable and practical for perhaps a very long time.

This code is compiled and tested by me today. The featured Output is an actual screen-scrape of the console window this code ran in just now.

#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_WARNINGS

#include <windows.h>
#include <stdio.h>

HANDLE hConsole = NULL;

char *mssg[] = {
    "The 1st mssg",
    "The 2nd mssg",
    "The 3rd mssg",
    "The 4th mssg",
    "The 5th mssg",
    "The 6th mssg",
    "The 7th mssg",
    "The 8th mssg",
    "The 9th mssg",
    "The 10th mssg",
};


int main() 
{
int iii;
COORD point;

    /* Removed needless check for hConsole==NULL per comment 
    * from of Andreas Wenzel */
    hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    if(hConsole == INVALID_HANDLE_VALUE)
    {
        printf("STDOUT not available");
        return 0;
    }
    point.X = 30;
    point.Y = 10;
    for(iii=0; iii<10; iii++)
    {
        SetConsoleCursorPosition(hConsole, point);
        printf("%s", mssg[iii]);
        point.Y += 2;
        if( iii == 4 )
        {
            point.X = 50;
            point.Y = 10;
        }
    }
    return 0;
}

Output:


                              The 1st mssg        The 6th mssg

                              The 2nd mssg        The 7th mssg

                              The 3rd mssg        The 8th mssg

                              The 4th mssg        The 9th mssg

                              The 5th mssg        The 10th mssg