# Beginner's C question

Bob Busby
I have a long char array of empty spaces and newlines for each row. I want to take in a coordinate pair (row,column) and be able to change that corresponding point into an asterisk. For the life of me I can't figure out how to index correctly. I know the below attempt is wrong. Any help would be appreciated.

#define ROWS 20
#define COLS 40
#define SIZE (ROWS * (COLS + 1) + 1)

char screen[(COLS+1)*ROWS + 1];
...

void setPixel(int r, int c) {

screen[r * (c + -2 + r)] = '*'; /* -2 is needed for correct indexing
* since the newline characters make
* the indices of screen uneven
*/
}

Homework Helper
If the first row and column are 0, you want something like

r*(COLS+1) + c

For the first row when r = 0, column number c is just position c in the array.

Otherwise, you need to skip over r complete rows which is r times (COLS+1) positions, then add the column number.

If you want to count rows and columns starting at 1 not 0, you want something like
(r-1)*(COLS+1) + (c-1)

Bob Busby
Thanks a lot. I have one more question. I'm trying to come up with a function that will clear the screen. By that I mean fill it with white space except at the end of each row which should be a newline. I can't figure out the math for placing the newlines.

void clearScreen(void) {
int c, r;
c = 1;
for(r = 0; r < SIZE; ++r) {
printf("%d ",r-c);//fmod(r - c,COLS));
//HERE'S THE PROBLEM
if(fmod((COLS + 1) + (r - c),COLS) == 0) {
//screen[r] = '\n';
printf(" aa ");
++c;
} else {
screen[r] = ' ';
}
}
for(r = 0; r < SIZE; ++r) {
printf("%c",screen[r]);
}
}

Mentor
EDIT: Revise no. of columns and rows.
Why are you using fmod? Your two arguments to this function are both ints, and fmod works with floats or doubles.

Do you know the dimensions of the screen? I seem to remember them as being 80 columns wide by 25 rows down. Since your screen is 40 by 20, you could have a loop that runs 20 times, with each iteration writing 39 spaces + a newline character.

Last edited:
Grep
It would be a kindness to people helping you if you started wrapping your code in CODE tags. There's a button in the editor for posting. Or you can do it manually by placing your code between the right tags. Put [ CODE ] at the start and [ /CODE ] at the end of the block of code. I added spaces there so it wouldn't think I'm using the tags myself, so remove all the spaces between [ and ].
Code:
void clearScreen(void) {
int c, r;
c = 1;
for(r = 0; r < SIZE; ++r) {
printf("%d ",r-c);//fmod(r - c,COLS));
//HERE'S THE PROBLEM
if(fmod((COLS + 1) + (r - c),COLS) == 0) {
//screen[r] = '\n';
printf(" aa ");
++c;
} else {
screen[r] = ' ';
}
}
for(r = 0; r < SIZE; ++r) {
printf("%c",screen[r]);
}
}

Isn't that much nicer?

Bob Busby
Sorry about the formatting. It's set up like this:

R COLS \n
O
W
S

So the actual number of columns is COLS + 1. I have revised the function but it still doesn't seem to be working correctly.

Code:
void clearScreen(void) {
int c, r;
c = 1;
for(r = 0; r < ROWS; ++r) { /* Loops through ROWS rows */
for(c = 0; c < (COLS + 2); ++c) { /* Loops through each column per row.
* The + 2 is because there is a
* newline character at screen[COLS + 1]
* and the loop starts at 0. */
if(c == COLS) {
screen[OFFSET(r,c)] = '\n';
} else {
screen[OFFSET(r,c)] = ' ';
}
}
}
}

Mentor
Can you be more specific?

Grep
I whipped a test program for it that seems to work ok. I don't see the need for the +2. The newline character ('\n') is one character. The backslash is just an "escape character".

In theory, if you're working with 40 columns, you don't even need the extra space for the newline character. If you hit the end of the line, most consoles will wrap to the next line after printing the character in column 40. Which means the newline will actually come into effect after it has wrapped to the next line, which will cause an extra blank line. If the line ends before the end of the screen, then the newline has space already.

But anyways, ignoring that, this seems to work ok. Note that it's a test program, and I print a $character so I can see where the line ended, and start and end banners. But I'll paste that in and you can see what I did. I had to recreate the OFFSET macro. Basically, I made the +2's into +1's. Seems to work, but I did it rather quickly and haven't checked things all that much. Code: #include <stdio.h> #define ROWS 20 #define COLS 40 #define SIZE (ROWS * (COLS + 1) + 1) #define OFFSET(r, c) (r * (COLS + 1) + c) char screen[(COLS+1)*ROWS + 1]; void clearScreen(void) { int c, r; c = 1; for(r = 0; r < ROWS; ++r) { /* Loops through ROWS rows */ for(c = 0; c < (COLS + 1); ++c) { /* Loops through each column per row. * The + 1 is because there is a * newline character at screen[COLS + 1] * and the loop starts at 0. */ if(c == COLS) { screen[OFFSET(r,c)] = '\n'; } else { screen[OFFSET(r,c)] = ' '; } } } } int main(int argc, char *argv[]) { int i; clearScreen(); printf("--- START ---\n"); for (i = 0; i < SIZE; i++) { if (screen[i] == '\n') { putchar('$');
}
putchar(screen[i]);
}
printf("--- END ---\n");
}

Bob Busby
I want an array of size (ROWS * (COLS + 1) + 1). COLS is the number of visible columns. The newline character will be the (COLS + 1) column. That's why there is a + 2. The other + 1 is for the null character.

I added this at the end of the clearScreen function.
Code:
 screen[SIZE - 1] = "\0";
but for some reason when I print it out I get 2. Any ideas why? EDIT: Now I'm getting # so I'm guessing it's random.

Mentor
This code
Code:
screen[SIZE - 1] = "\0";
is not doing what you think.

screen is an array of char, but "\0" is a string, and this assignment will try to store the address of this string constant into the array.

What are you trying to do with this assignment?

Grep
I want an array of size (ROWS * (COLS + 1) + 1). COLS is the number of visible columns. The newline character will be the (COLS + 1) column. That's why there is a + 2. The other + 1 is for the null character.

I don't see why you need to add a null character on the end of every line. At the end of the entire array, yes, it's a good idea. But why at the end of every line?

I added this at the end of the clearScreen function.
Code:
 screen[SIZE - 1] = "\0";
but for some reason when I print it out I get 2. Any ideas why? EDIT: Now I'm getting # so I'm guessing it's random.

You used quotes, which means it's a string. A string is a pointer in C. You should have gotten at least a warning from your compiler on that. You're printing out a character out of a pointer. You need to use single quotes to tell the compiler that it's a character. It should be more like:

Code:
 screen[SIZE - 1] = '\0';