Split up program with 2 dimensional arrays into Functions (C) - c

I've written a program in C which allows me to move around in a "room" which is a 2 dimensional array. It works fine, but now I am running into issues when trying to split it up into functions. I might approach it completely wrong as I've only worked in Visual Basic, where stuff like this is much easier.
The void functions with printf also work perfectly fine.
Here's my code:
#include <stdio.h>
void instruction(void) {
printf("Move: W=up, D=right, S=down, A=left an apply with RETURN.\n");
}
void wall(void) {
printf("##### You are in front of a wall. Please move somewhere else! #####\n");
}
int runter(roomxy, y, x, index) {
roomxy[y][x] = 0;
y = y + 1;
if (y>3 || y<0) {
y = y - 1;
wall();
index--;
return (index);
}
return (roomxy[y][x]);
}
void main() {
char c[2];
int steps;
int i;
int j;
int k;
int room[4][4] = { 0 };
int ypos = 0;
int xpos = 0;
room[ypos][xpos] = 1;
for(j=0; j<4; j++) {
for(k=0; k<4; k++) {
printf("%d ", room[j][k]);
}
printf("\n");
}
printf("How many steps do you want to make? (Number from 1 to 50.)\n");
scanf("%d", &steps);
if (steps>0 && steps<51) {
for (i=1; i<=steps; i++) {
instruction();
scanf("%s", c);
if (c[0] == 'S' || c[0] == 's') {
room = runter(room, ypos, xpos, i);
/*room[ypos][xpos] = 0;
ypos = ypos + 1;
if (ypos>3 || ypos<0) {
ypos = ypos - 1;
wall();
i--;
}*/
}
else if (c[0] == 'W' || c[0] == 'w') {
room[ypos][xpos] = 0;
ypos = ypos - 1;
if (ypos>3 || ypos<0) {
ypos = ypos + 1;
wall();
ypos = ypos + 1;
wall();
i--;
}
}
else if (c[0] == 'D' || c[0] == 'd') {
room[ypos][xpos] = 0;
xpos = xpos + 1;
if (xpos>3 || xpos<0) {
xpos = xpos - 1;
wall();
i--;
}
}
else if (c[0] == 'A' || c[0] == 'a') {
room[ypos][xpos] = 0;
xpos = xpos - 1;
if (xpos>3 || xpos<0) {
xpos = xpos + 1;
wall();
i--;
}
}
else {printf("##### ERROR: Only type in W, D, S or A! #####\n"); i--;}
room[ypos][xpos] = 1;
printf("Ihre Position:\n");
for(j=0; j<4; j++) {
for(k=0; k<4; k++) {
printf("%d ", room[j][k]);
}
printf("\n");
}
}
}
else {printf("##### Please enter number from 1 to 50! #####\n");}
}
The error I am getting is "subscripted value is neither array nor pointer nor vector".
I don't know how to move on as I am completely stuck at trying to figure out how functions with arrays work in C.
I've also read about the typedef argument, but I also don't really know how to work with it.
Obviously I am a bloody noob at programming in general.
Thank you guys in advance!

Your source code is muddled, so there are a number of things to fix.
First, change void main() to int main(void). That is just required by the C standard; main must be either int main(void) or int main(int argc, char *argv[]) in normal situations.
Next, you must declare parameter types when you declare a function. int runter(roomxy, y, x, index) is wrong because it fails to say what types the parameters are. Likely, you want either int runter(int roomxy[][4], int y, int x, int index) or int runter(int *roomxy, int y, int x, int index). The former passes the entire array (by way of a pointer to its first subarray) to runter. The latter passes a pointer to a specific element. The first should be used if runter needs to work with multiple elements of the array. The second should be used if runter needs to work with only a specific element. However, using the second form requires additional changes in your program, and it requires use of pointers that you may not have learned about yet, so I am going to omit discussion of that.
Then, it is not clear what you want runter to return. In one place inside the function, you have return (index);. In another, you have return (roomxy[[y][x]);. It is not clear to me whether the index and roomxy[y][x] are two possible values of one kind of thing you want to return or whether they are different kinds of things. If they are the same kind of thing, okay. But if they represent different things, it generally does not make sense for a function to return one or the other.
In any case, return statements do not need parentheses. return index; and return roomxy[y][x] are fine.
Where you call runter, you have room = runter(room, ypos, xpos, i);. This does not make sense because room is an array but runter returns an int. You cannot assign an int to an array. Perhaps you meant room[ypos][xpos] = runter(room, ypos, xpos, 1);. (If so, then it does appear you want runter to work with a single element, so the pointer-to-an-element solution would be better. But you can get the program working and then worry about that.)

I have modified your source. in runter() you are returning int and have catch with room which is pointer(2 dimensional). it's impossible.
Add on to this you should have declare datatype in int runter(roomxy, y, x, index). I have corrected it.
#include <stdio.h>
void instruction(void) {
printf("Move: W=up, D=right, S=down, A=left an apply with RETURN.\n");
}
void wall(void) {
printf("##### You are in front of a wall. Please move somewhere else! #####\n");
}
void runter(int roomxy[][4], int y, int x, int index) {
roomxy[y][x] = 0;
y = y + 1;
if (y>3 || y<0) {
y = y - 1;
wall();
index--;
// return (index);
}
// return (roomxy[y][x]);
}
int main() {
char c[2];
int steps;
int i;
int j;
int k;
int room[4][4] = { 0 };
int ypos = 0;
int xpos = 0;
room[ypos][xpos] = 1;
for(j=0; j<4; j++) {
for(k=0; k<4; k++) {
printf("%d ", room[j][k]);
}
printf("\n");
}
printf("How many steps do you want to make? (Number from 1 to 50.)\n");
scanf("%d", &steps);
if (steps>0 && steps<51) {
for (i=1; i<=steps; i++) {
instruction();
scanf("%s", c);
if (c[0] == 'S' || c[0] == 's') {
/* room[ypos][xpos] = */runter(room, ypos, xpos, i);
room[ypos][xpos] = 0;
ypos = ypos + 1;
if (ypos>3 || ypos<0) {
ypos = ypos - 1;
wall();
i--;
}
}
else if (c[0] == 'W' || c[0] == 'w') {
room[ypos][xpos] = 0;
ypos = ypos - 1;
if (ypos>3 || ypos<0) {
ypos = ypos + 1;
wall();
/* ypos = ypos + 1;
wall();*/
i--;
}
}
else if (c[0] == 'D' || c[0] == 'd') {
room[ypos][xpos] = 0;
xpos = xpos + 1;
if (xpos>3 || xpos<0) {
xpos = xpos - 1;
wall();
i--;
}
}
else if (c[0] == 'A' || c[0] == 'a') {
room[ypos][xpos] = 0;
xpos = xpos - 1;
if (xpos>3 || xpos<0) {
xpos = xpos + 1;
wall();
i--;
}
}
else {printf("##### ERROR: Only type in W, D, S or A! #####\n"); i--;}
room[ypos][xpos] = 1;
printf("Ihre Position:\n");
for(j=0; j<4; j++) {
for(k=0; k<4; k++) {
printf("%d ", room[j][k]);
}
printf("\n");
}
}
}
else {printf("##### Please enter number from 1 to 50! #####\n");}
return 0;
}

Related

How can I have this grid wrap around on all sides?

I have an assignment where I need to let the user create the height and width of a grid. Then be able to place "ships" onto that grid at any x and y coordinates. Then you can place a storm on a certain section of that grid to then prompt and see if a storm is overlapped with a ship. I have done that successfully but I can't get the storm to wrap around the grid. For example if the grid is 20x20 and I put a storm that starts on the 20th spot over it should shift to the 1 position on the left side of the grid. Here is that code I have a diagram of what it looks like. (Note there is no physical grid getting printed to the terminal)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct ship {
// Declaring variables
char shipName[21];
int x, y, w, h;
char direction;
struct ship *next;
} Ship;
//Declaring head of linked list
Ship *head = NULL;
void newShip(int x, int y, char direction, char *shipName) {
//Adding ships to linked list
Ship *new_ship = (Ship *)malloc(sizeof(Ship));
strcpy(new_ship->shipName, shipName);
new_ship->x = x;
new_ship->y = y;
new_ship->direction = direction;
new_ship->next = head;
head = new_ship;
}
void shipMovement(int time, int w, int h) {
//Moving ships
Ship *current = head;
while (current != NULL) {
if (current->direction = 'U') {
current->y = (current->y + time) % h;
}
else if (current->direction = 'D') {
current->y = (current->y - time + h) % h;
}
else if (current->direction = 'L') {
current->x = (current->x - time + w) % w;
}
else if (current->direction = 'R') {
current->x = (current->x + time) % w;
}
else {
printf("Invalid Direction!\n");
}
current = current->next;
}
}
void checkAffShips(int x, int y, int w, int h, char **affShips, int *numAffShips) {
//Checking if ships are affected by storm
Ship *current = head;
while (current != NULL) {
if (((current->x >= x) && (current->x < x + w)) && ((current->y >= y) && (current->y < y + h))) {
// add shipName to list of affected ships
affShips[*numAffShips] = (char *)malloc(sizeof(char) * 21);
strcpy(affShips[(*numAffShips)++], current->shipName);
}
current = current->next;
}
}
//Main Function------------------------------------------------------------------
int main() {
int w, h;
int stormWidth, stormHeight;
scanf("%d %d", &w, &h);
char userInput;
//Looping through commands
while (scanf(" %c", &userInput) != 4) {
if (userInput == '1') {
int x, y;
char direction[21], shipName[21];
scanf("%d %d %s %s", &x, &y, direction, shipName);
newShip(x, y, direction[0], shipName);
} else if (userInput == '2') {
int time;
scanf("%d", &time);
shipMovement(time, w, h);
} else if (userInput == '3') {
int x, y, w, h;
scanf("%d %d %d %d", &x, &y, &w, &h);
char *affShips[1000];
int numAffShips = 0;
checkAffShips(x, y, w, h, affShips, &numAffShips);
printf("%d\n", numAffShips);
for (int i = 0; i < numAffShips; i++) {
printf("%s\n", affShips[i]);
free(affShips[i]);
}
} else if (userInput == '4') {
break;
}
else {
printf("Invalid Input!\n");
}
}
return 0;
}
Here is the documentation:
(https://i.stack.imgur.com/K28We.png)
I've tried a bunch of different stuff so maybe I just didn't do something right in my attempts but I'm sure someone can help figure this out.
Your test for the affected ships is wrong. In your example, if you have a storm of size 2 in the bottom right corner (19, 19), a ship in the top left corner (0, 0) isn't caught, because 0 is not in the range [19, 21).
One way to fix this is to move the point you want to test into the "extended range" if it lies below the starting point of the storm. (The "extended range" is the range that does not wrap and so extends to two times the width of the board.)
So to test whether a one-dimensional point lies in a cyclic range, you could use a function like this:
int in_cyclic_range(int n, int lower, int width, int wrap)
{
if (n < lower) n += wrap;
return (n < lower + width);
}
If you now test n in the whole range from [0, 20) on the storm at 19 of width 2, with in_cyclic_range(n, 19, 2, 20), you will get hits at locations 19 and 0.
In order to test if a ship is affected by a storm, you need the storm position and dimensions, the ship position and the grid dimensions.
In your code, you use w, and h for the grid dimensions and a new set of variables w and h for the storm dimensions in the local scope of if (userInput == '3') { ... }. This is confusing and makes the grid dimensions inaccessible from this part of the code. You should use stormWidth and stormHeight for the storm dimensions and pass both these and the grid dimensions to the checkAffShips function.
The test in checkAffShips for the wrapped coordinate system is more complicated than what you wrote to take into account the wrapped parts of the storm area: as many as 3 extra rectangles.
Also note these issues:
using explicit names for the grid and storm dimensions would help avoid confusion.
the w and h fields in the Ship structure are unused.
reading strings with scanf should be protected by specifying the maximum number of characters to store into the destination array before the null terminator.
newShip should not use strcpy directly as the shipName argument could be longer than the destination array.
you should check the return value of scanf() to detect invalid or missing input.
if (current->direction = 'U') sets current->direction and evaluates to true. You should use == instead of =
the array of shipnames affShips should be allocated by checkAffShips.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct ship {
char shipName[21];
int x, y;
char direction;
struct ship *next;
} Ship;
//Declaring head of linked list
Ship *head = NULL;
/* string copy function with size limitation */
void mystrcpy(char *dest, size_t size, const char *src) {
while (size > 1) {
*dest++ = *src++;
size--;
}
if (size > 0)
*dest = '\0';
}
void newShip(int x, int y, char direction, const char *shipName) {
//Adding ship to linked list
Ship *new_ship = (Ship *)malloc(sizeof(*new_ship));
if (new_ship) {
mystrcpy(new_ship->shipName, sizeof new_ship->shipName, shipName);
new_ship->x = x;
new_ship->y = y;
new_ship->direction = direction;
new_ship->next = head;
head = new_ship;
}
}
void shipMovement(int time, int w, int h) {
//Moving ships
for (Ship *current = head; current != NULL; current = current->next) {
if (current->direction == 'U') {
current->y = (current->y + time) % h;
} else
if (current->direction == 'D') {
current->y = (current->y + h - time % h) % h;
} else
if (current->direction == 'L') {
current->x = (current->x + w - time % w) % w;
} else
if (current->direction == 'R') {
current->x = (current->x + time) % w;
} else {
printf("%s: invalid Direction '%c'!\n",
current->shipName, current->direction);
}
}
}
char **checkAffShips(int stormX, int stormY, int stormWidth, int stormHeight,
int gridWidth, int gridHeight,
int *pnumAffShips)
{
char **affShips = NULL;
int numAffShips = 0;
for (Ship *current = head; current != NULL; current = current->next) {
int x = current->x;
int y = current->y;
//Checking if ship is affected by storm
if (((x >= stormX && x < stormX + stormWidth) ||
(stormX + stormWidth > gridWidth && x < (stormX + stormWidth) % gridWidth)) &&
((y >= stormY && y < stormY + stormHeight) ||
(stormY + stormHeight > gridHeight && y < (stormY + stormHeight) % gridHeight)))
{
// add shipName to list of affected ships
affShips = realloc(affShips, sizeof(*affShips) * (numAffShips + 1));
affShips[numAffShips++] = strdup(current->shipName);
}
}
*pnumAffShips = numAffShips;
return affShips;
}
//Main Function------------------------------------------------------------------
int main() {
int gridWidth, gridHeight;
if (scanf("%d %d", &gridWidth, &gridHeight) != 2)
return 1;
char userInput;
//Looping through commands
while (scanf(" %c", &userInput) == 1) {
if (userInput == '1') {
int x, y;
char direction[21], shipName[21];
if (scanf("%d %d %20s %20s", &x, &y, direction, shipName) != 4)
return 1;
newShip(x, y, direction[0], shipName);
} else
if (userInput == '2') {
int time;
if (scanf("%d", &time) != 1)
return 1;
shipMovement(time, gridWidth, gridHeight);
} else
if (userInput == '3') {
int x, y, stormWidth, stormHeight;
if (scanf("%d %d %d %d", &x, &y, &stormWidth, &stormHeight) != 4)
return 1;
char **affShips;
int numAffShips = 0;
affShips = checkAffShips(x, y, stormWidth, stormHeight,
gridWidth, gridHeight, &numAffShips);
printf("%d\n", numAffShips);
for (int i = 0; i < numAffShips; i++) {
printf("%s\n", affShips[i]);
free(affShips[i]);
}
free(affShips);
} else
if (userInput == '4') {
break;
} else {
printf("Invalid Input!\n");
}
}
return 0;
}

How to make sure that by default all points are initially in the 2D array in C?

I was doing my homework when I ran into a problem. The meaning of the program is that I set the size of a 2d array, then I write the directions in which the "turtle" will move, then the program outputs it. But when I run the program, even without instructions, the terminal outputs the following for me, for example
I can't figure out what my mistake is, by default the program should write
without that `o' at the beginning, how can I fix it?
My code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int hor;
int vert;
int x = 0;
int y = 0;
int i;
int a;
char symbol = 'z';
scanf("%d%d", &vert, &hor);
char* pole = (char*)malloc(vert * hor * sizeof(char));
for (i = 0; i < vert; i++)
{
for(a = 0; a < hor; a++)
pole[i * vert + a] = '.';
}
pole[x *vert + y] = 'o';
while(symbol != 'x')
{
scanf("%c", &symbol);
if (symbol == '^') x--;
else if (symbol == 'v') x++;
else if (symbol == '>') y++;
else if (symbol == '<') y--;
else if (symbol == 'o') pole[x *vert + y] = 'o';
if(y < 0)
y = vert - 1;
else if(y > vert)
y = 0;
if(x < 0)
x = hor - 1;
else if(x > hor)
x = 0;
}
for (i = 0; i < vert; i++)
{
for(a = 0; a < hor; a++)
{
printf("%c", pole[i *vert + a]);
}
printf("\n");
}
free(pole);
return 0;
}
I tried to remove the "o", but nothing helped me:(

Getting unexpected results in CS50 readability problem

In solving this readability problem, I have been getting some weird unexpected results(expected Grade 16+, getting Grade 10 etc etc), I am not being able to figure out where the bug is or how can I solve it, please help me figure out the bug. The codes are as follows:
//includes
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <math.h>
//global variables
int lc; //letter count
int wc; //word count
int sc; //sentence count
bool awc; //already word counted
double L; //average number of letters per 100 words
double S; //average number of sentences per 100 words
float index;
//function declaration
int count_letters(string x);
int count_words(string x);
int count_sentences(string x);
//main
int main(void)
{
string text = get_string("text : ");
count_letters(text);
printf("%i letters\n", lc);
count_words(text);
printf("%i words\n", wc);
count_sentences(text);
printf("%i sentences\n", sc);
L = lc / wc * 100.0f;
S = sc / wc * 100.0f;
index = (0.0588 * L) - (0.296 * S) - 15.8;
if(index < 1)
{
printf("Before Grade 1\n");
}
else if(index >= 16)
{
printf("Grade 16+\n");
}
else
{
printf("Grade %i\n", (int) round(index));
}
}
//functions
int count_letters(string x)
{
lc = 0;
for(int i = 0, n = strlen(x); i < n; i++)
{
if((x[i] >= 'a' && x[i] <= 'z') || (x[i] >= 'A' && x[i] <= 'Z'))
{
lc += 1;
}
}
return lc;
}
int count_words(string x)
{
wc = 0;
awc = false;
for(int i = 0, n = strlen(x); i < n; i++)
{
if((x[i] >= 'a' && x[i] <= 'z') || (x[i] >= 'A' && x[i] <= 'Z'))
{
if(awc == false)
{
wc += 1;
awc = true;
}
}
if(x[i] == ' ')
{
awc = false;
}
}
return wc;
}
int count_sentences(string x)
{
sc = 0;
for(int i = 0, n = strlen(x); i < n; i++)
{
if(x[i] == '.' || x[i] == '!' || x[i] == '?')
{
sc += 1;
}
}
return sc;
}
The number of letters, words and sentences from these functions are correct so far so I think the problem lies in the main section, probably something to do with the variable type of "L" and "S" or the index formulae, please help me figure out where the problem is. Thank you
here are some of the tests: sentences(expected results)
1.One fish. Two fish. Red fish. Blue fish. (Before Grade 1)
2.Harry Potter was a highly unusual boy in many ways. For one thing, he hated the summer holidays more than any other time of year. For another, he really wanted to do his homework, but was forced to do it in secret, in the dead of the night. And he also happened to be a wizard. (Grade 5)
3.A large class of computational problems involve the determination of properties of graphs, digraphs, integers, arrays of integers, finite families of finite sets, boolean formulas and elements of other countable domains. (Grade 16+)
L = lc / wc * 100.0f;
wrong
L = 100.0f * lc / wc;
right.
When both operands of / are integers, the result is integer as well, so 5/3 == 1.
the OPs code contains several problems, as discussed in the comments to the question.
The following proposed code:
corrects those problems exposed in the comments
cleanly compiles
strongly suggest all those 'global' variables be moved to inside the appropriate functions and when needed else where be passed as parameters.
and now, the proposed code:
//includes
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <math.h>
//global variables
int lc; //letter count
int wc; //word count
int sc; //sentence count
bool awc; //already word counted
double L; //average number of letters per 100 words
double S; //average number of sentences per 100 words
double i;
//function declaration
int count_letters(string x);
int count_words(string x);
int count_sentences(string x);
//main
int main(void)
{
string text = get_string("text : ");
count_letters(text);
printf("%i letters\n", lc);
count_words(text);
printf("%i words\n", wc);
count_sentences(text);
printf("%i sentences\n", sc);
L = lc / wc * 100.0;
S = sc / wc * 100.0;
i = (0.0588 * L) - (0.296 * S) - 15.8;
if(i < 1.0)
{
printf("Before Grade 1\n");
}
else if(i >= 16.0)
{
printf("Grade 16+\n");
}
else
{
printf("Grade %i\n", (int) round(i));
}
}
//functions
int count_letters(string x)
{
lc = 0;
for( size_t i = 0, n = strlen(x); i < n; i++)
{
if((x[i] >= 'a' && x[i] <= 'z') || (x[i] >= 'A' && x[i] <= 'Z'))
{
lc += 1;
}
}
return lc;
}
int count_words(string x)
{
wc = 0;
awc = false;
for( size_t i = 0, n = strlen(x); i < n; i++)
{
if((x[i] >= 'a' && x[i] <= 'z') || (x[i] >= 'A' && x[i] <= 'Z'))
{
if(awc == false)
{
wc += 1;
awc = true;
}
}
if(x[i] == ' ')
{
awc = false;
}
}
return wc;
}
int count_sentences(string x)
{
sc = 0;
for( size_t i = 0, n = strlen(x); i < n; i++ )
{
if(x[i] == '.' || x[i] == '!' || x[i] == '?')
{
sc += 1;
}
}
return sc;
}

Why is array[i][-1] == 0? How does one prevent undefined variables from being used? [duplicate]

This question already has answers here:
Are negative array indexes allowed in C?
(9 answers)
Closed 6 years ago.
/**
* fifteen.c
*
* Computer Science 50
* Problem Set 3
*
* Implements Game of Fifteen (generalized to d x d).
*
* Usage: fifteen d
*
* whereby the board's dimensions are to be d x d,
* where d must be in [DIM_MIN,DIM_MAX]
*
* Note that usleep is obsolete, but it offers more granularity than
* sleep and is simpler to use than nanosleep; `man usleep` for more.
*/
#define _XOPEN_SOURCE 500
#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
// constants
#define DIM_MIN 3
#define DIM_MAX 9
// board
int board[DIM_MAX][DIM_MAX];
int b;
// dimensions
int d;
// prototypes
void clear(void);
void greet(void);
void init(void);
void draw(void);
bool move(int tile);
bool won(void);
int main(int argc, string argv[])
{
// ensure proper usage
if (argc != 2)
{
printf("Usage: fifteen d\n");
return 1;
}
// ensure valid dimensions
d = atoi(argv[1]);
if (d < DIM_MIN || d > DIM_MAX)
{
printf("Board must be between %i x %i and %i x %i, inclusive.\n",
DIM_MIN, DIM_MIN, DIM_MAX, DIM_MAX);
return 2;
}
// open log
FILE* file = fopen("log.txt", "w");
if (file == NULL)
{
return 3;
}
// greet user with instructions
greet();
// initialize the board
init();
// accept moves until game is won
while (true)
{
// clear the screen
clear();
// draw the current state of the board
draw();
// log the current state of the board (for testing)
for (int i = 0; i < d; i++)
{
for (int j = 0; j < d; j++)
{
fprintf(file, "%i", board[i][j]);
if (j < d - 1)
{
fprintf(file, "|");
}
}
fprintf(file, "\n");
}
fflush(file);
// check for win
if (won())
{
printf("ftw!\n");
break;
}
// prompt for move
printf("Tile to move: ");
int tile = GetInt();
// quit if user inputs 0 (for testing)
if (tile == 0)
{
break;
}
// log move (for testing)
fprintf(file, "%i\n", tile);
fflush(file);
// move if possible, else report illegality
if (!move(tile))
{
printf("\nIllegal move.\n");
usleep(500000);
}
// sleep thread for animation's sake
usleep(500000);
}
// close log
fclose(file);
// success
return 0;
}
/**
* Clears screen using ANSI escape sequences.
*/
void clear(void)
{
printf("\033[2J");
printf("\033[%d;%dH", 0, 0);
}
/**
* Greets player.
*/
void greet(void)
{
clear();
printf("WELCOME TO GAME OF FIFTEEN\n");
usleep(2000000);
}
/**
* Initializes the game's board with tiles numbered 1 through d*d - 1
* (i.e., fills 2D array with values but does not actually print them).
*/
void init(void)
{
for(int i = 0, j = 0, k = ((d*d)-1); i < d; j++, k--)
{
if(j == d)
{
i = i + 1;
j = 0;
}
board[i][j] = k;
}
if((d*d)%2 == 0)
{
board[(d-1)][(d-2)] = 2;
board[(d-1)][(d-3)] = 1;
}
board[(d-1)][(d-1)] = 0;
b = board[(d-1)][(d-1)];
}
/**
* Prints the board in its current state.
*/
void draw(void)
{
for(int i = 0, j = 0; i !=(d-1) || j!=d; j++)
{
if(j == d)
{
i = i + 1;
j = 0;
printf("\n");
}
if(board[i][j] == 0) //b used to be 99
{
printf(" _");
}
else
{
printf(" %2d", board[i][j]);
}
}
printf("\n");
}
/**
* If tile borders empty space, moves tile and returns true, else
* returns false.
*/
bool move(int tile)
{
//find tile
for(int i = 0, j = 0; i !=(d-1) || j!=d; j++)
{
if(j == d)
{
i = i + 1;
j = 0;
}
if (board[i][j] == tile)
{
//check if tile position is in valid perimeter of blank space
if (board[i+1][j] == b)
{
board[i+1][j] = tile;
board[i][j] = 0;
b = board[i][j];
return true;
}
if (board[i-1][j] == b)
{
board[i-1][j] = tile;
board[i][j] = 0;
b = board[i][j];
return true;
}
if (board[i][j+1] == b)
{
board[i][j+1] = tile;
board[i][j] = 0;
b = board[i][j];
return true;
}
if (board[i][j-1] == b)
{
printf("%i", board[i][j-1]);
board[i][j-1] = tile;
board[i][j] = 0;
b = board[i][j];
return true;
}
}
}
return false;
}
/**
* Returns true if game is won (i.e., board is in winning configuration),
* else false.
*/
bool won(void)
{
for(int i = 0, j = 0, k = 1; i !=(d-1) || j!=d; j++)
{
if(j == d)
{
i = i + 1;
j = 0;
}
if (k == (d*d)-1)
{
return true;
}
if (board[i][j] == k)
{
k = k + 1;
}
}
return false;
}
I originally had
board[(d-1)][(d-1)] = 0;
equal to 99 along with the move function look for 99. For my problem set I was supposed to use 0. Once I changed 99 to 0, for some reason 0 is being found if board[i][j-1] even if that means board[2][-1]. Why is that allow/why does that equal 0? and how can I disable this?
You have int board[DIM_MAX][DIM_MAX]; where #define DIM_MIN 3 and the memory allocated for elements are contiguous, so typically you will access board[1][2] by using board[2][-1]. But this is undefined behavior, which allows anything to happen, and you mustn't use that.
Quote from N1570 J.2 Undefined behavior:
An array subscript is out of range, even if an object is apparently accessible with the
given subscript (as in the lvalue expression a[1][7] given the declaration int
a[4][5]) (6.5.6).
board[2][-1]. Why is that allow
C does allow you access out of range of an array. But it is Undefined Behavior.
why does that equal 0?
By accident. It's Undefined Behavior and it could be anything.

Reverse Polish converter

I am trying to make a reverse Polish printer which can perform the following operation-
Inputs:
(a+(b*c))
((a+b)*(z+x))
((a+t)*((b+(a+c))^(c+d)))
Outputs:
abc*+
ab+zx+*
at+bac++cd+^*
This is my code:
#include <stdio.h>
#include <string.h>
char pop(int t);
void push(int c, int t);
int main()
{
int z;
scanf("%d", &z);
char *a[100];
int i = 0;
int q = z;
while (q-- > 0)
{
char v[400];
scanf("%s", &v);
int t;
for (t = 0; t < strlen(v); t++) //loop to put the values and signs in the 2 stacks
{
if ((v[t] == '*') || (v[t] == '+') || (v[t] == '-') || (v[t] == '^'))
{
push(v[t], 2);
}
else if (v[t] == ')')
{
int y = pop(2);
push(y, 1);
}
else
{
push(v[t], 1);
}
}
int k = 0;
char c;
while ((c = pop(1)) !='\0') //loop to put elements in the array v
{
if (c != '(')
{
v[k++] = c;
}
}
v[k--] = '\0';
int m;
for (m=0; m != k; m++, k--) //for reversing the string
{
char t = v[m];
v[m] = v[k];
v[k] = t;
}
a[i++] =v;
printf("%s",a[i - 1]);
}
int p;
for (p = 0; p <z ; p++) //printing the elements
printf("%s\n",*a[p]);
return 0;
}
char ac[400];
char as[400];
int ic = 0;
int is = 0;
void push(int c,int t)
{
if (t == 1 && ic != 400)
ac[ic++] = c;
else if (t == 2 && is != 400)
as[is++] = c;
}
char pop(int t)
{
if (t == 1 && ic != 0)
return ac[--ic];
if (t == 2 && is != 0)
return as[--is];
return '\0';
}
But it is not even inputting properly and I am not able to figure out what are the mistakes in this code.Please help to figure out what are the problems.
after inputing the no of test cases i.e.int z and first line if input
it crashes
This is due to the
printf("%s\n",*a[p]);
as BLUEPIXY noticed, *a[p] is a char; but %s expects a char *, thus you need
printf("%s\n", a[p]);
and regarding v is out of scope, the crucial factor is not the scope (visibility), but the storage duration (lifetime) of v - its lifetime ends when execution of the block with which it is associated ends, and the value of a pointer a[i] to it becomes indeterminate; by changing
a[i++] =v;
to
a[i++] = strdup(v);
you can remedy that.

Resources