Home > Mobile >  Filling 2D ARRAY with characters from string
Filling 2D ARRAY with characters from string

Time:11-21

I'm trying to fill an array with some selected characters from string. 2 columns have to stay empty, but this is how it's working for me. Every symbol should be equal to number of rows. Like ball sort game.. Some advice? Thanks.

void generator(const int rows, const int columns, char field[rows][columns]){  
    // seed
    srand(time(NULL));

    int random_index;

    // choosing empty columns (they'll be by side)
    int clear_column[2];
    // choosing random number in range of columns
    clear_column[0] = rand() % (columns 1);
    // adding  1 index to already choosen number
    clear_column[1] = clear_column[0] 1;
    // if choosen number is equal to number of columns => second empty column will be on the left side
    if ( clear_column[0] == columns)
    {
        clear_column[1] = clear_column[0]-1;
    }

    // variable to store all symbols 
    char store_symbol[10] = "^@#&* -/$";
    // variable to store used symbols
    int store_index[10] = {0,0,0,0,0,0,0,0,0};
    
    

    // ** i = columns; k = rows

    // loops all columns
    for (int i = 0; i < columns; i  )
    {
        // loops all rows
        for (int k = 0; k < rows; k  )
        {
            // adding empty columns
            if ( i == clear_column[0] || i == clear_column[1])
            {
                field[k][i] = ' ';
            }
            else{
                int got_symbol = 0;
                while (got_symbol == 0)
                {
                    random_index = rand() % rows;

                    if ( store_index[random_index] <= rows)
                    {
                        field[i][k] = store_symbol[random_index];
                        store_index[random_index]  = 1;
                        got_symbol = 1;
                        break;
                    }
                    
                }
                
            }
            
        }
        
    }

This is how it should look.

result

CodePudding user response:

To fix the potential Undefined Behaviour in this function, when rows does not equal columns, the indices here

field[i][k] = store_symbol[random_index];

need to be flipped

field[k][i] = store_symbol[random_index];

The following allows rows plus one of each character in the array:

if (store_index[random_index] <= rows) {

Change <= to < to limit the number of each character in the array to a maximum of rows.

The following

int clear_column[2];
clear_column[0] = rand() % (columns 1);
clear_column[1] = clear_column[0] 1;
if (clear_column[0] == columns) {
    clear_column[1] = clear_column[0]-1;
}

introduces an off-by-one error. If clear_column[0] is equal to columns, then the only column to be cleared will be the last one, via clear_column[1] (clear_column[1] = clear_column[0] - 1;).

i will never reach columns in the loop.

There are a few solutions to this:

Ensure columns > 1, find the first column within the valid range minus, and take the next column over.

int clear_column[2] = { rand() % (columns - 1) };
clear_column[1] = clear_column[0]   1;

Or, find the first column to clear within the valid range, and adjust the second in either direction:

int clear_column[2] = { rand() % columns };             
clear_column[1] = clear_column[0]   (clear_column[0] == columns - 1 ? -1 : 1);

Aside: This distributes empty columns more frequently to the last two columns (clear_column[0] being columns - 1 or columns - 2 results in the same pattern.

Or, you could wrap the second column to clear around to the start of the array:

clear_column[0] = rand() % columns;
clear_column[1] = (clear_column[0]   1) % columns;

Or, completely randomize your cleared columns.

int clear_column[2] = { rand() % columns };      
while ((clear_column[1] = rand() % columns) == clear_column[0]);

These last two do produce different patterns, though.


There is a problem with the requirement

Every symbol should be equal to number of rows

when the number of elements minus the number of blank spaces (rows times two) is not equal to the square of rows, since you allow rows different characters up to rows times each.

Instead you should allow columns - 2 different characters up to rows times each.


Here is an example of the aforementioned changes applied to your function:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define SYM "^@#&* -/$?"
#define MAX_SYM 10
#define def(c, a, i, d) (c > i ? atoi(a[i]) : d)

void generator(const int rows, const int columns, char field[rows][columns])
{
    int clear_column[2] = { rand() % columns };
    clear_column[1] = (clear_column[0]   1) % columns;

    char store_symbol[MAX_SYM] = SYM;
    int store_index[MAX_SYM] = { 0 };

    for (int i = 0; i < columns; i  ) {
        for (int k = 0; k < rows; k  ) {
            if (i == clear_column[0] || i == clear_column[1]) {
                field[k][i] = ' ';
                continue;
            }

            while (1) {
                int random_index = rand() % (columns - 2);

                if (store_index[random_index] < rows) {
                    field[k][i] = store_symbol[random_index];
                    store_index[random_index]  = 1;
                    break;
                }
            }
        }
    }
}

int main(int argc, char **argv)
{
    int r = def(argc, argv, 1, 4);
    int c = def(argc, argv, 2, 6);

    if (r < 1 || c < 1 || r > MAX_SYM || c > MAX_SYM) {
        fprintf(stderr, "Invalid dimensions %dx%d\n", r, c);
        return EXIT_FAILURE;
    }

    char map[r][c];

    srand((unsigned) time(NULL));
    generator(r, c, map);

    for (int i = 0; i < r; i  ) {
        printf("|");
        for (int j = 0; j < c; j  ) {
            printf(" %c |", map[i][j]);
        }

        putchar('\n');
    }
}
  • Related