6

I want to be clear, yes this is a homework related question, and no I don't expect you to do my homework for me. I love coding and I'm just looking for advice.

Having said that, I'm a creating the Game of Life in C. Here is some code to show I've been working on this:

void create_area(void){
int table[24][80];
int i,j;
int xvalue=10,yvalue=10;
table[10][10] = 2;


/*for(j=0; j<24; j++){
    for(i=0; i<80; i++){
        table[j][i] = 1;
    }
}*/

for(j=0; j<24; j++){
    for(i=0; i<80; i++){
        printf(" ",table[j][i]);
    }
    printf("\n");
}

/*if(xvalue=10){
    if(yvalue=10){
        printf("O", table[xvalue][yvalue]);
    }
}*/

/*for(j=0; j<24; j++){
    for(i=0; i<80; i++){
        if(xvalue=0){
            if(yvalue=0){
                printf("O",table[xvalue][yvalue]);
            }
        }
    }
}*/
}

My main method isn't shown here, but it takes care of finding the number of arguments and the argument strings and putting them into coordinates with two arrays that I make (an x_array and y_array). The method show above is basically create the grid in the terminal. The parameters for create_area is void for now (because I just want to test values to see if it works, which is why I have two int variables: xvalue and yvalue). But the idea is that create_area will take a x value and y value and initialize the character 'O' where the cell would begin. A lot of the code is commented out because I'm trying to figure stuff out.

My question: How do I insert a character within my 2d array so that it displays that character in a spot on the grid when looking at it in the terminal?

So far I created my 2d array, and used two for loops to go through it and print spaces. But I'm trying to figure out how to print a char for example at table[10][10]. I tried a few things, but the character won't display at the certain location, only at the bottom left of my screen. I think I'm missing something simple.

Any help would be appreciated.

DsDude
  • 135
  • 1
  • 8
  • Sorry, what do u try to make in the loop with `printf`? Do you sure that it outputs some visible characters? – Denis Sologub Jan 14 '17 at 19:34
  • It's not clear for me if you don't get the print result that you expect, or if you are looking for a way to print something in a specific location on screen – Christophe Jan 14 '17 at 19:36
  • @Christophe The latter, I'm looking for a way to print something a specific location on the terminal. I made an array that's 80x24 and used two for loops that make each table[j][i] a space, so basically I have an "invisible" map in my terminal that's like a rectangle, and I want to put a character at certain locations in that map. – DsDude Jan 14 '17 at 19:45
  • 1
    Many pro software gates have strict code formatting guidelines. Usually there is whitespace around comparison operators, and after commas, after semicolons in for loops and around `=` in C. It's harder to read and tackier when everything is crammed together. White space provides separation that makes things easier to assimilate. If you want to cut whitespace in a way that really helps, your formatting style is good, the way you brace things. Braces on new lines (some people take that to an extreme) entails too much scrolling to read the code. – clearlight Jan 14 '17 at 20:22
  • 1
    "`printf(" ", table[j][i]);`" this is a serious code issue and if you enable compiler warnings (gcc: `-Wall -Werror -Wextra -pedantic-errors`) you will find and fix many critical issues, and the code you write will be safer and standards compliant. – cat Jan 14 '17 at 21:40

5 Answers5

4

If you want to represent a grid of characters, then you should use data type char instead of int and character constants (e.g. '1') instead of integer constants (e.g. 1). The main issue, however, is that statement printf(" ",table[j][i]); always prints a space as you missed the format specifier in the format string (e.g. "%d" for integers, or "%c" for character data type). I do not know how your grid shall look like exactly, but maybe the following fragment helps:

void create_area(void){
  char table[24][80];
  int i,j;
  int xvalue=10,yvalue=10;

  for(j=0; j<24; j++){
    for(i=0; i<80; i++){
        table[j][i] = '1';
    }
  }

  table[10][10] = '0';

  for(j=0; j<24; j++){
    for(i=0; i<80; i++){
        printf("%c",table[j][i]);
    }
    printf("\n");
  }
  ...
Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
  • This does exactly what I wanted it to do, but Stephan, the reason why I use a int table and not a char is because when I run my program in the terminal, for example: ./gameoflife 1 2 3 4 I'm taking the argv, which in this case is 4 strings ( 1 2 3 4), I'm pairing them as coordinates so like (1,2) and (3,4) and I want to be able to place a character on the grid using my coordinates, do you understand? – DsDude Jan 14 '17 at 19:53
  • 1
    The coordinates may still be integers (also in the code above the coordinates are integers, whereas the value stored at a particular coordinate is a character). So reading in argv-values into integer coordinates is OK and does not require that the table is a 2D-array with cells of datatype `int`. Note that in `char table[24][80]` the array dimensions `24` and `80` are integers, whereas `char` defines the data type of the cells. OK? – Stephan Lechner Jan 14 '17 at 20:02
  • Yeah, @Inline made me realize this, I can't believe I missed that – DsDude Jan 14 '17 at 20:09
4

I agree with the other answers here, but let me provide another perspective.

You should separate data from presentation. Here the array is your data (it could also be bool table[24][80], because in the Game of Life each cell is described by 1 bit). The code that displays your data should examine each data element (see whether it's 0 or 1) and output 1 char. For that, you can use putchar:

putchar(table[j][i] ? 'x' : ' ')

or printf:

printf("%c", table[j][i] ? 'x' : ' ')

It's good to separate data from presentation because this makes it easier for you to change (improve) each of them separately. For example, if you decide to replace x by * in your visualization, the corresponding code is in one place. If you decide to optimize your storage by allocating 1 byte per cell (and not 1 int per cell) - the change is also relatively localized.

anatolyg
  • 26,506
  • 9
  • 60
  • 134
2

For option. You actually can fill your table with spaces, modify it and then print

char table[24][80]; // char is better

memset(table, ' ', sizeof(table[0][0]) * 24 * 80); // Fill table with spaces

table[10][10] = 'J'; // Your first custom char
table[20][20] = '0'; // Another custom char

for(j=0; j<24; ++j) {
    for(i=0; i<80; ++i) {
        printf("%c",table[j][i]); // You forget write "%c" to print char
        //putchar(table[j][i]) // This will also work
    }
    printf("\n");
}
Inline
  • 2,566
  • 1
  • 16
  • 32
  • Since my 2d array is of type int, this doesn't work properly since you made table[10][10] = 'J' – DsDude Jan 14 '17 at 19:43
  • 1
    @DsDude In first place you don't need 2d array of integers, you need chars. – Inline Jan 14 '17 at 19:48
  • I see what you're saying, I upvoted your comment, it was insightful. But read my comment on Stephan Lechner's post because there's a reason I use an int table and not a char table. – DsDude Jan 14 '17 at 19:55
  • 1
    @DsDude I don't understand, for array indexing `C` uses `size_t` and it is undependable on data type. So you can use `size_t` or `int` coordinates/indexes for `char table[n][m]` – Inline Jan 14 '17 at 19:59
  • Oh I think I see what you're say, so for example: when I do ./gameoflife 1 2 3 4, the '1 2 3 4' are separate strings, and you don't see it in the code shown above, but in my 'main' function I use atoi() to take these strings and change them to ints, but what you saying is that I can use these ints in the char table so for example: char table[1][2] and table[3][4]. I believe I understand now. – DsDude Jan 14 '17 at 20:07
  • 1
    @DsDude For indexing better to use size_t (it's unsigned and standart) https://stackoverflow.com/questions/32325479/how-to-get-size-t-from-string – Inline Jan 14 '17 at 20:09
1

See this description for printf. In C the character is just a some integer number, so you should specify a format to output it like a character %c or like an integer (decimal) %d.

   for(j=0; j<24; j++) {

        for(i=0; i<80; i++){

            if (table[j][i] == 1) { // it's a code of some character that fills your array (As I saw in commented block you used 1)
                printf(" ");
            } else {
                printf("%c",table[j][i]);
            }
        }

        printf("\n");
    }

P.S. For profi, I know it's not an optimal code but it will be easy for him to understand.

Denis Sologub
  • 7,277
  • 11
  • 56
  • 123
1

You can use the %hhu scan code for printing unsigned char. This means there is no need to change your int table data type.

printf("%hhu", table[j][i]); % table[j][i] contains integers

Hint: the unsigned char range is 0 - 255 and the numbers which are not placed in this range will not displayed as you may expect.

hmofrad
  • 1,784
  • 2
  • 22
  • 28