1

I am trying to create a grid in C with this form

+--+--+--+
|  |  |  |
+--+--+--+
|  |  |  |
+--+--+--+

and so on.The user will determine how many columns and rows wants. In the code below the logic is that one execution of the row loop will create this shape

   +--+--+
   |  |  |
   +--+--+  

What I mean is that one row is this shape not a single line. For some reason it is creating more rows than wanted in a multiplying style example for n=3 it creates 4 rows and for n=6 it creates 2 more rows and for 9 it creates 4 more rows etc. Any ideas why is this happening? Keep in mind that n=3*n(start of the programm) because we want the shape mentioned above to be one row,also the main reason I am doing this is because the grid must end in a +--+ line.

#include <stdio.h>

int main(void)
{
    int n,m,i,j;
    scanf("%d",&n);
    scanf("%d",&m);
    n=3*n;

    for(i=0;i<n;i++){
        if(i%2==0){
            printf("+");
        }
        for(j=0;j<m;j++){

            if(i%2!=0 && i!=n-1){
                printf("|  ");
            }
            if(i%2==0){

                printf("--+");
            }
        }
        if(i%2!=0 && i!=n-1){
            printf("|  ");
        }

        printf("\n");
    }
}
user3386109
  • 34,287
  • 7
  • 49
  • 68
J.Antoniou
  • 11
  • 4
  • The problem is `n=3*n`. I would write a function that outputs a `+---+` line, and a function that outputs a `| |` line. Then the loop needs to call those functions `n` times. And the first function is called one more time after the loop. OTOH, you can also patch your code with `n = 2*n+1`. – user3386109 Nov 08 '18 at 18:43
  • I think you've made life harder for yourself by using single letter variables that don't lend themselves to easy reading and reasoning. Thinking about variable names can often lead to insights about the problem. For example, what is `n`? It means one thing when the user enters it, but then it's multiplied by 3. What does it mean after that? – Tim Randall Nov 08 '18 at 18:53

2 Answers2

2

Some suggestions:

  1. Use Meaningful Variable Names
  2. Prompt User For Input

The basic shape you need to print is:

+--
|

With that in mind, here is a simple solution:

#include <stdio.h>

int main(void)
{
    int row, col, r, c;

    printf("Enter Number Of Rows And Columns: ");
    scanf("%d", &row);
    scanf("%d", &col);

    for(r = 0; r < row; r++)
    {
        /* Draw Top */
        for(c = 0; c < col; c++)
            printf("+--");
        printf("+\n");

        /* Draw Middle */
        for(c = 0; c < col; c++)
            printf("|  ");
        printf("|\n");
    }

    /* Draw Bottom */
    for(c = 0; c < col; c++)
        printf("+--");
    printf("+\n");
}

Output

$ ./main.exe
Enter Number Of Rows And Columns: 1 1
+--+
|  |
+--+

$ ./main.exe
Enter Number Of Rows And Columns: 2 6
+--+--+--+--+--+--+
|  |  |  |  |  |  |
+--+--+--+--+--+--+
|  |  |  |  |  |  |
+--+--+--+--+--+--+

$ ./main.exe
Enter Number Of Rows And Columns: 6 2
+--+--+
|  |  |
+--+--+
|  |  |
+--+--+
|  |  |
+--+--+
|  |  |
+--+--+
|  |  |
+--+--+
|  |  |
+--+--+
Fiddling Bits
  • 8,712
  • 3
  • 28
  • 46
2

As user3386109 commented to the question, the problem is the n = 3*n;. It should be n = 2*n + 1;, because each cell is 2×2 characters, and you need one extra row of characters.

Consider this counter-example:

#include <stdlib.h>
#include <locale.h>
#include <wchar.h>
#include <stdio.h>

const wchar_t  names[] = L"123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

static void wide_grid(FILE *out, const int rows, const int cols)
{
    int  row, col;

    /* We can only do single-character cell names. */
    if (rows > wcslen(names) || cols > wcslen(names))
        return;    

    /* Top left corner of the grid, including the top edge of that cell. */
    fwprintf(out, L"┌──");

    /* Top edges of each cell in the topmost row, except the leftmost cell. */
    for (col = 2; col <= cols; col++)
        fwprintf(out, L"┬──");

    /* Top right corner of the grid. */
    fwprintf(out, L"┐\n");

    /* Cells for the top row, including their left edges. */
    for (col = 1; col <= cols; col++)
        fwprintf(out, L"│%lc%lc", names[0], names[col-1]);

    /* The right edge of the last cell in the top row. */
    fwprintf(out, L"│\n");

    /* Loop over the rest of the cell rows. */
    for (row = 2; row <= rows; row++) {

        /* Top edge of the first cell on this row. */
        fwprintf(out, L"├──");

        /* Top edges of the rest of the cells. */
        for (col = 2; col <= cols; col++)
            fwprintf(out, L"┼──");

        /* Right edge of the grid. */
        fwprintf(out, L"┤\n");

        /* Cells themselves, including their left edges. */
        for (col = 1; col <= cols; col++)
            fwprintf(out, L"│%lc%lc", names[row-1], names[col-1]);

        /* Right edge of the grid. */
        fwprintf(out, L"│\n");
    }

    /* Bottom left corner of the grid, including the cell bottom. */
    fwprintf(out, L"└──");

    /* Bottom edges of the rest of the cells. */
    for (col = 2; col <= cols; col++)
        fwprintf(out, L"┴──");

    /* Bottom right corner of the grid. */
    fwprintf(out, L"┘\n");
}


int main(int argc, char *argv[])
{
    const int  max = wcslen(names);
    int        rows, cols;
    char       dummy;

    if (!setlocale(LC_ALL, ""))
        fprintf(stderr, "Warning: Your C library does not support your current locale.\n");

    if (fwide(stdout, 1) < 1)
        fprintf(stderr, "Warning: Your C library does not support wide character standard output.\n");

    if (argc != 3) {
        fprintf(stderr, "\n");
        fprintf(stderr, "Usage: %s [ help ]\n", argv[0]);
        fprintf(stderr, "       %s ROWS COLUMNS\n", argv[0]);
        fprintf(stderr, "\n");
        return EXIT_SUCCESS;
    }

    if (sscanf(argv[1], " %d %c", &rows, &dummy) != 1 || rows < 1) {
        fprintf(stderr, "%s: Invalid number of rows.\n", argv[1]);
        return EXIT_FAILURE;
    }
    if (rows > max) {
        fprintf(stderr, "%s: Too many rows. The maximum is %d.\n", argv[1], max);
        return EXIT_FAILURE;
    }

    if (sscanf(argv[2], " %d %c", &cols, &dummy) != 1 || cols < 1) {
        fprintf(stderr, "%s: Invalid number of columns.\n", argv[2]);
        return EXIT_FAILURE;
    }
    if (cols > max) {
        fprintf(stderr, "%s: Too many columns. The maximum is %d.\n", argv[2], max);
        return EXIT_FAILURE;
    }

    wide_grid(stdout, rows, cols);

    return EXIT_SUCCESS;
}

This program uses wide-character output, so you should be able to use any Unicode glyphs your terminal font supports. These are from the Box Drawing set. (Some Windows users may need Microsoft-specific extensions to above, to get the output right, but as I don't use Windows, I'm omitting those.)

You need to supply the number of rows and columns on the command line as well. Running it without any parameters shows a short help text.

Each cell is labeled, with both row and column label taken from the names array. You can allow larger grids by adding label characters to that array.

Each line or loop in the wide_grid() is commented, to explain what the purpose of each snippet of code is.

Instead of a single nested loop, and conditional cases within those, we build the grid part by part:

┌──  ┬──  ..  ┬──  ┐

│11  │12  ..  │1c  │

├──  ┼──  ..  ┼──  ┤   ╲
                        row = 2 .. rows
│r1  │r2  ..  │rc  │   ╱

:    :        :    :

└──  ┴──  ..  ┴──  ┘

Here's what you see if you run it with arguments 5 12:

┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│11│12│13│14│15│16│17│18│19│1A│1B│1C│
├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
│21│22│23│24│25│26│27│28│29│2A│2B│2C│
├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
│31│32│33│34│35│36│37│38│39│3A│3B│3C│
├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
│41│42│43│44│45│46│47│48│49│4A│4B│4C│
├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
│51│52│53│54│55│56│57│58│59│5A│5B│5C│
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
Nominal Animal
  • 38,216
  • 5
  • 59
  • 86