i am getting the error "a3.c:221:20: error: storage size of ‘gold’ isn’t known" for all 4 of my item structs. My code is as follows:
void parser(int argc, char **argv)
{
FILE * rooms;
char * theString;
char * theToken;
int numberElements;
int side;
int k;
int placeInt;
int posX;
int posY;
char a[ROOM_STRING_LENGTH];
numberElements = 0;
rooms = fopen(argv[1], "r");
if(rooms == NULL)
{
printf("error opening file\n");
}
while(fgets(a, ROOM_STRING_LENGTH, rooms) != NULL)
{
theString = malloc((sizeof(char)*(strlen(a)+1)));
strcpy(theString, a);
for(theToken = strtok(theString, " "); theToken; theToken = strtok(NULL, " "))
{
printf("the next token: %s\n", theToken);
if(theToken[0] == '1')
{
}
if(theToken[0] == 'd')
{
switch(theToken[1])
{
case 'e':
{
side = 1;
placeInt = theToken[2] - '0';
printf("the side: %d, the place: %d\n", side, placeInt);
break;
}
case 'w':
{
side = 2;
placeInt = theToken[2] - '0';
printf("the side: %d, the place: %d\n", side, placeInt);
break;
}
case 's':
{
side = 3;
placeInt = theToken[2] - '0';
printf("the side: %d, the place: %d\n", side, placeInt);
break;
}
case 'n':
{
side = 4;
placeInt = theToken[2] - '0';
printf("the side: %d, the place: %d\n", side, placeInt);
break;
}
default:
{
break;
}
}
}
else if(theToken[0] == 'g' || theToken[0] == 'm' || theToken[0] == 'p' || theToken[0] == 'h')
{
k = 0;
while(k <= (strlen(theToken)))
{
switch(theToken[k])
{
case 'g':
posY = theToken[1] - '0';
posX = theToken[3] - '0';
struct item gold;
gold.Xposition = posX;
gold.Yposition = posY;
printf("the y position: %d, the x position: %d\n", posY, posX);
break;
case 'm':
posY = theToken[1] - '0';
posX = theToken[3] - '0';
struct item monster;
monster.Xposition = posX;
monster.Yposition = posY;
printf("the y position: %d, the x position: %d\n", posY, posX);
break;
case 'p':
posY = theToken[1] - '0';
posX = theToken[3] - '0';
struct item potion;
potion.Xposition = posX;
potion.Yposition = posY;
printf("the y position: %d, the x position: %d\n", posY, posX);
break;
case 'h':
posY = theToken[1] - '0';
posX = theToken[3] - '0';
struct item hero;
hero.Xposition = posX;
hero.Yposition = posY;
printf("the y position: %d, the x position: %d\n", posY, posX);
break;
}
k++;
}
}
else if(theToken == NULL)
{
printf("end of file");
}
numberElements++;
}
if(theToken == NULL)
{
printf("You've reached the end of the line\n");
}
printf("%d\n", numberElements);
}
free(theString);
fclose(rooms);
}
struct item
{
int Xposition;
int Yposition;
};
Also, I was wondering how i would go about accessing the information i just stored into those structs in a different function.
As keltar and nonsensickle already mentioned, you have to define struct item before you can use an instance of it:
struct item { int x; int y; }; // this must come first
// ...
struct item item1 {4, 2};
You could, however, use a pointer before the definition, as long as you have already declared the struct:
struct item; // declaration, no definition
// ...
struct item *pitem1;
// ...
struct item { int x; int y; }; // defined later
To use a struct's members in another function, you could pass either a struct or a struct* to that function:
void use_struct (struct item i)
{
int a = i.x, b = i.y;
}
void use_struct_pointer (struct item *pi)
{
int a = pi->x, b = pi->y;
}
int main()
{
struct item i {4, 2};
use_struct(i);
use_struct_pointer(&i);
return 0;
}
Related
The program:
evaluates postfix and prefix expressions
reverse a string
parenthesis balancing
decimal to binary conversion
infix to postfix conversion
There a some extra characters (emojis) appended in the output. I would like to fix that.
Also I have used two pop functions with int and char return type how can I reduce it to one single function.
extra characters in the output of decimal to binary conversion, also that one extra left parenthesis when printing "balanced parenthesis"
This a first year college project.
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#define MAX 20
int stack[MAX], opp1, opp2, top = -1;
struct stack
{
char stck[20];
int top;
}
s;
void push(int x)
{
top++;
stack[top] = x;
}
int pop()
{
char c;
c = stack[top];
top = top - 1;
printf("%c", c);
}
char pop1()
{
if (top == -1)
return -1;
else
return stack[top--];
}
void postfixeval()
{
char postfix[20];
int res, i;
gets(postfix);
for (i = 0; postfix[i] != '\0'; i++)
{
if (isdigit(postfix[i]))
{
push(postfix[i] - 48);
}
else
{
opp2 = pop();
opp1 = pop();
switch (postfix[i])
{
case '+':
push(opp1 + opp2);
break;
case '-':
push(opp1 - opp2);
break;
case '*':
push(opp1 *opp2);
break;
case '/':
push(opp1 / opp2);
break;
case '^':
res = pow(opp1, opp2);
break;
}
}
}
printf("result is %d \n", pop());
}
void prefixeval()
{
int len;
char prefix[20];
int res, i;
gets(prefix);
len = strlen(prefix);
for (i = len - 1; i >= 0; i--)
{
if (isdigit(prefix[i]))
{
push(prefix[i] - 48);
}
else
{
opp1 = pop();
opp2 = pop();
switch (prefix[i])
{
case '+':
push(opp1 + opp2);
break;
case '-':
push(opp1 - opp2);
break;
case '*':
push(opp1 *opp2);
break;
case '/':
push(opp1 / opp2);
break;
case '^':
res = pow(opp1, opp2);
push(res);
break;
}
}
}
printf("result is %d \n", pop());
}
int match(char a, char b)
{
if (a == '[' && b == ']')
return 1;
if (a == '{' && b == '}')
return 1;
if (a == '(' && b == ')')
return 1;
}
int check(char exp[])
{
int i;
char temp;
for (i = 0; i < strlen(exp); i++)
{
if (exp[i] == '(' || exp[i] == '{' || exp[i] == '[')
push(exp[i]);
if (exp[i] == ')' || exp[i] == '}' || exp[i] == ']')
if (top == -1)
{
return 0;
}
else
{
temp = pop();
if (!match(temp, exp[i]))
{
printf("Mismatched parentheses are : ");
printf("%c and %c\n", temp, exp[i]);
return 0;
}
}
}
if (top == -1)
{
printf("Balanced Parentheses\n");
return 1;
}
else
{
return 0;
}
}
void dectobin(int n)
{
while (n != 0)
{
push(n % 2);
n = n / 2;
}
while (top != -1)
{
printf("%d", pop());
}
}
int priority(char x)
{
if (x == '(')
return 0;
if (x == '+' || x == '-')
return 1;
if (x == '*' || x == '/')
return 2;
}
void intopost()
{
char exp[100];
char *e, x;
printf("Enter the expression : \n");
scanf("%s", exp);
printf("\n");
e = exp;
while (*e != '\0')
{
if (isalnum(*e))
printf("%c ", *e);
else if (*e == '(')
push(*e);
else if (*e == ')')
{
while ((x = pop1()) != '(')
printf("%c ", x);
}
else
{
while (priority(stack[top]) >= priority(*e))
printf("%c ", pop1());
push(*e);
}
e++;
}
while (top != -1)
{
printf("%c ", pop1());
}
}
int main()
{
int ch, i, len;
char postfix[20], prefix[20], str[30];
do {
printf("\n----STACK APPLICATIONS----\n");
printf("1.postfix expression evaluation\n2.prefix expression evaluation\n3.reverse a string\n4.paranthesis balancing\n5.decimal to binary\n6.infix to postfix\n7.exit\n");
printf("enter choice");
scanf("%d", &ch);
switch (ch)
{
case 1:
{
printf("enter postfix expression\n");
scanf("%c", &postfix);
postfixeval();
break;
}
case 2:
{
printf("enter prefix expression\n");
scanf("%c", prefix);
prefixeval();
break;
}
case 3:
{
printf("enter string\n");
scanf("%s", str);
len = strlen(str);
for (i = 0; i < len; i++)
{
push(str[i]);
}
printf("reversed string is:");
for (i = 0; i < len; i++)
{
pop();
}
break;
}
case 4:
{
char exp[20];
int valid;
printf("Enter an algebraic expression : \n");
scanf("%s", exp);
valid = check(exp);
if (valid == 1)
{
printf("Valid expression\n");
}
else
{
printf("Invalid expression\n");
}
break;
}
case 5:
{
int dec;
printf("enter decimal number\n");
scanf("%d", &dec);
dectobin(dec);
break;
}
case 6:
{
intopost();
break;
}
case 7:
{
exit(0);
}
default:
printf("invalid choice\n");
}
} while (ch != 7);
}
Here are the additional characters appended with the output
Here is one 'improvement' that you should learn about 'C'.
printf(
"1.postfix expression evaluation\n"
"2.prefix expression evaluation\n"
"3.reverse a string\n"
"4.paranthesis balancing\n"
"5.decimal to binary\n"
"6.infix to postfix\n"
"7.exit\n"
);
The compiler will 'join-up' those 'segments' (because there is no comma between a close quote and the next open quote.)
Once you have that, you can go back to basics and get this much displaying and functioning:
printf(
// "1.postfix expression evaluation\n"
// "2.prefix expression evaluation\n"
// "3.reverse a string\n"
// "4.paranthesis balancing\n"
// "5.decimal to binary\n"
// "6.infix to postfix\n"
"7.exit\n"
);
Don't try to run before you can walk...
To demonstrate 'incremental development' and 'learning/exploring':
// test.c - string segments in source code
#include <stdio.h>
int main() {
printf(
"Hello "
"World!\n"
);
return 0;
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 11 months ago.
Improve this question
I'm studying about data structure coding.
I built a calculator using a stack.
infix to postfix and result
However, I want to get the result after all completing the input.
And I want to "out" the input with an end.
the last line is example when it debug.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STACK_SIZE 100
#define MAX_EXPR_SIZE 100
enum {
lparen = -9,
rparen,
plus,
minus,
times,
divide,
mod,
eos,
operand
};
int stack[MAX_STACK_SIZE];
char expr[MAX_EXPR_SIZE], postexpr[MAX_EXPR_SIZE];
int pos = 0;
static int isp[] = { 0, 19, 12, 12, 13, 13, 13, 0 };
static int icp[] = { 20, 19, 12, 12, 13, 13, 13, 0 };
void add_stack(int *top, int item) {
if (*top >= MAX_STACK_SIZE - 1)
printf("Error: Stack is full\n");
stack[++*top] = item;
}
int delete_stack(int *top) {
if (*top == -1)
printf("Error: Stack is empty\n");
return stack[(*top)--];
}
int get_token(char *symbol, int *n) {
*symbol = expr[(*n)++];
switch (*symbol) {
case '(': return lparen;
case ')': return rparen;
case '+': return plus;
case '-': return minus;
case '*': return times;
case '/': return divide;
case '%': return mod;
case 0:
case '\n': return eos;
default: return operand;
}
}
void print_token(int p) {
switch (p) {
case plus:
printf("+");
postexpr[pos++] = '+';
break;
case minus:
printf("-");
postexpr[pos++] = '-';
break;
case times:
printf("*");
postexpr[pos++] = '*';
break;
case divide:
printf("/");
postexpr[pos++] = '/';
break;
case mod:
printf("%");
postexpr[pos++] = '%';
break;
case eos:
printf(" ");
break;
}
}
void postfix(void) {
char symbol;
int token;
int n = 0;
int top = 0;
stack[0] = eos;
token = get_token(&symbol, &n);
for(; token != eos; token = get_token(&symbol, &n)) {
if (token == operand) {
printf("%c", symbol);
postexpr[pos++] = symbol;
}
else if (token == rparen) {
while (stack[top] != lparen)
print_token(delete_stack(&top));
delete_stack(&top);
} else {
while (isp[stack[top] + 9] >= icp[token + 9])
print_token(delete_stack(&top));
add_stack(&top, token);
}
}
while ((token = delete_stack(&top)) != eos)
print_token(token);
printf("\n");
}
int eval(void) {
int token;
char symbol;
int op1, op2;
int n = 0;
int top = 0;
stack[0] = eos;
token = get_token(&symbol, &n);
for(; token != eos; token = get_token(&symbol, &n)) {
if (token == operand)
add_stack(&top, symbol - '0');
else {
op2 = delete_stack(&top);
op1 = delete_stack(&top);
switch (token) {
case plus: add_stack(&top, op1 + op2); break;
case minus: add_stack(&top, op1 - op2); break;
case times: add_stack(&top, op1 * op2); break;
case divide: add_stack(&top, op1 / op2); break;
case mod: add_stack(&top, op1 % op2); break;
}
}
}
return delete_stack(&top);
}
int main(void) {
printf("Input expression : ");
scanf("%s", expr);
printf("Postfix expression: ");
postfix();
strcpy(expr, postexpr);
printf("Evaluation of the expression : %d", eval());
}
this is example when it done
input //
(8*6)+2/4
(8*6)+4/2
out //
print//
postfix (8*6)+2/4
result (8*6)+2/4
postfix (8*6)+4/2
result (8*6)+4/2
//
Here are some problems and possible improvements to your code:
printf("%") has undefined behavior. You should write printf("%%") or simply putchar('%')
you should parse numbers with multiple digits
you should skip spaces and TABs
you should detect invalid characters
you should detect invalid expressions
you should not use global variables
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STACK_SIZE 100
enum {
error = -10,
lparen = -9,
rparen,
plus,
minus,
times,
divide,
mod,
eos,
operand, /* 0 and above are operand values */
};
static int const isp[] = { 0, 19, 12, 12, 13, 13, 13, 0 };
void add_stack(int *stack, int *top, int item) {
if (*top >= MAX_STACK_SIZE - 1) {
printf("Error: Stack is full\n");
return;
}
stack[++*top] = item;
}
int delete_stack(int *stack, int *top) {
if (*top < 0) {
printf("Error: Stack is empty\n");
return eos;
}
return stack[(*top)--];
}
int get_token(const char *expr, int *pos) {
for (;;) {
int c = expr[*pos];
if (c == '\0' || c == '\n')
return eos;
*pos += 1;
if (c == ' ' || c == '\t')
continue;
if (c >= '0' && c <= '9') {
int value = c - '0';
while ((c = expr[*pos]) >= '0' && c <= '9') {
*pos += 1;
value = value * 10 + (c - '0');
}
return value;
}
switch (c) {
case '(': return lparen;
case ')': return rparen;
case '+': return plus;
case '-': return minus;
case '*': return times;
case '/': return divide;
case '%': return mod;
default: *pos -= 1; return error;
}
}
}
void print_token(char *postexpr, int *ppos, int token) {
int pos = *ppos;
switch (token) {
case error: postexpr[pos++] = '?'; break;
case lparen: postexpr[pos++] = '('; break;
case rparen: postexpr[pos++] = ')'; break;
case plus: postexpr[pos++] = '+'; break;
case minus: postexpr[pos++] = '-'; break;
case times: postexpr[pos++] = '*'; break;
case divide: postexpr[pos++] = '/'; break;
case mod: postexpr[pos++] = '%'; break;
case eos: break;
default:
/* insert a space between numbers */
if (pos > 0 && postexpr[pos - 1] >= '0' && postexpr[pos - 1] <= '9')
postexpr[pos++] = ' ';
pos += sprintf(postexpr + pos, "%d", token);
break;
}
*ppos = pos;
postexpr[pos] = '\0';
}
int put_error(const char *message, const char *expr, int col) {
if (col < 0) {
printf("%s\n", message);
} else {
printf("%s at column %d\n", message, col + 1);
printf("%s\n%*s\n", expr, col + 1, "^");
}
return -1;
}
int postfix(const char *expr, char *postexpr) {
int stack[MAX_STACK_SIZE];
int token, n = 0, top = 0, pos = 0, last = eos;
stack[0] = eos;
while ((token = get_token(expr, &n)) != eos) {
if (token == error) {
return put_error("syntax error", expr, n);
}
if (token >= operand) {
if (last >= operand) {
return put_error("missing operator", expr, n - 1);
}
print_token(postexpr, &pos, token);
} else
if (token == rparen) {
if (last < operand && last != rparen) {
return put_error("missing operand", expr, n - 1);
}
while (stack[top] != lparen) {
if (stack[top] == eos) {
return put_error("invalid parenthesis", expr, n - 1);
}
print_token(postexpr, &pos, delete_stack(stack, &top));
}
delete_stack(stack, &top);
} else {
if (token == lparen) {
if (last >= operand || last == rparen) {
return put_error("missing operator", expr, n - 1);
}
} else {
if (last < operand && last != rparen) {
return put_error("missing operand", expr, n - 1);
}
while (isp[stack[top] - lparen] >= isp[token - lparen]) {
print_token(postexpr, &pos, delete_stack(stack, &top));
}
}
add_stack(stack, &top, token);
}
last = token;
}
if (last < operand && last != rparen) {
return put_error("missing operand", expr, n);
}
while ((token = delete_stack(stack, &top)) != eos) {
if (token == lparen) {
return put_error("unmatched parenthesis", expr, -1);
}
print_token(postexpr, &pos, token);
}
return 0;
}
int eval(const char *expr) {
int stack[MAX_STACK_SIZE];
int token, n = 0, top = 0;
stack[0] = eos;
while ((token = get_token(expr, &n)) != eos) {
if (token >= operand) {
add_stack(stack, &top, token);
} else {
int op2 = delete_stack(stack, &top);
int op1 = delete_stack(stack, &top);
switch (token) {
case plus: add_stack(stack, &top, op1 + op2); break;
case minus: add_stack(stack, &top, op1 - op2); break;
case times: add_stack(stack, &top, op1 * op2); break;
case divide: add_stack(stack, &top, op1 / op2); break;
case mod: add_stack(stack, &top, op1 % op2); break;
}
}
}
return delete_stack(stack, &top);
}
int main() {
char expr[100], postexpr[200];
for (;;) {
printf("Input expression: ");
if (scanf("%99s", expr) != 1)
break;
if (!postfix(expr, postexpr)) {
printf("Postfix expression: %s\n", postexpr);
printf("Evaluation of the expression: %d\n", eval(postexpr));
}
}
printf("Done.\n");
return 0;
}
Sample run:
Input expression: 1
Postfix expression: 1
Evaluation of the expression: 1
Input expression: 1+
missing operand at column 3
1+
^
Input expression: 1+1
Postfix expression: 1 1+
Evaluation of the expression: 2
Input expression: (1+2*3)
Postfix expression: 1 2 3*+
Evaluation of the expression: 7
Input expression: (1+2*3)*(3+4*5/6)
Postfix expression: 1 2 3*+3 4 5*6/+*
Evaluation of the expression: 42
Input expression: Done.
Here is code for my connect four game for exam. There are seven columns, if a number above 7 is entered it should say "Move not allowed", but if 0 is entered it should save the game.
When I enter 0 it says "Move not allowed". There is a code to save the game when 0 is entered but it says "Move not allowed" and doesn't go there. Can someone help?
#include <stdio.h>
#include <string.h>
typedef struct gameState{
int id;
char board[6][7];
int numberOfMoves;
char player1Name[20];
char player2Name[20];
}GameState;
void ShowMenu() {
printf("\n\n\n1. New Game \n");
printf("2. Load Game \n");
printf("3. Exit \n\n");
printf("Choose: ");
}
void ReadPlayerNames(char player1Name[20], char player2Name[20]) {
printf("\nName of first player:");
scanf("%s", player1Name);
printf("\nName of second player:");
scanf("%s", player2Name);
}
void PrintBoard(char board[6][7])
{
char header[] = " 1 2 3 4 5 6 7 ";
char border[] = "|---|---|---|---|---|---|---|";
printf("%s\n", header);
printf("%s\n", border);
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 7; j++)
{
printf("| %c ", board[i][j]);
}
printf("|\n");
printf("%s\n", border);
}
}
void ClearBoard(char board[6][7]) {
for (int i = 0; i < 6; i++){
for (int j = 0; j < 7; j++) {
board[i][j] = ' ';
}
}
}
// 1 - X wins, 2 - O wins, 0 - still playing
int CheckDiagonals(char board[6][7], int i, int j, int goUpRight){
int connectedO = 0;
int connectedX = 0;
while(i >= 0){
if (board[i][j] != ' '){
if (board[i][j] == 'X'){
connectedX++;
connectedO = 0;
if (connectedX == 4){
if (goUpRight = 0){
board[i][j] = 'Y'; //checking if x won, putting Y on places of x
board[i + 1][j + 1] = 'Y';
board[i + 2][j + 2] = 'Y';
board[i + 3][j + 3] = 'Y';
} else {
board[i][j] = 'Y';
board[i + 1][j - 1] = 'Y';
board[i + 2][j - 2] = 'Y';
board[i + 3][j - 3] = 'Y';
}
return 1;
}
} else {
connectedO++;
connectedX = 0;
if (connectedO == 4){
if (goUpRight = 0){
board[i][j] = 'Y';
board[i + 1][j + 1] = 'Y'; //checking if o won, putting Y on places of o
board[i + 2][j + 2] = 'Y';
board[i + 3][j + 3] = 'Y';
} else {
board[i][j] = 'Y';
board[i + 1][j - 1] = 'Y';
board[i + 2][j - 2] = 'Y';
board[i + 3][j - 3] = 'Y';
}
return 2;
}
}
} else {
connectedO = 0;
connectedX = 0;
}
i--;
if (goUpRight == 1){
j++;
}else{
j--;
}
}
return 0;
}
// 1 - X wins, 2 - O wins, 0 - still playing
int CheckRowsOrCols(char board[6][7], int rows){
int connectedO = 0;
int connectedX = 0;
int brI = 6;
int brJ = 7;
if (rows == 0){
brI = 7;
brJ = 6;
}
for (int i = 0; i < brI; i++){
for (int j = 0; j < brJ; j++) {
int pI = i, pJ = j;
if (rows == 0){
pI = j;
pJ = i;
}
if (board[pI][pJ] != ' '){
if (board[pI][pJ] == 'X'){
connectedX++;
connectedO = 0;
if (connectedX == 4){
if (rows == 0){
board[pI][pJ] = 'Y';
board[pI - 1][pJ] = 'Y';
board[pI - 2][pJ] = 'Y';
board[pI - 3][pJ] = 'Y';
} else {
board[pI][pJ] = 'Y';
board[pI][pJ - 1] = 'Y';
board[pI][pJ - 2] = 'Y';
board[pI][pJ - 3] = 'Y';
}
return 1;
}
} else {
connectedO++;
connectedX = 0;
if (connectedO == 4){
if (rows == 0){
board[pI][pJ] = 'Y';
board[pI - 1][pJ] = 'Y';
board[pI - 2][pJ] = 'Y';
board[pI - 3][pJ] = 'Y';
} else {
board[pI][pJ] = 'Y';
board[pI][pJ - 1] = 'Y';
board[pI][pJ - 2] = 'Y';
board[pI][pJ - 3] = 'Y';
}
return 2;
}
}
} else {
connectedO = 0;
connectedX = 0;
}
}
}
return 0;
}
// 1 - X wins, 2 - O wins, 0 - still playing
int CheckForWinner(char board[6][7]) {
int rezultat = CheckRowsOrCols(board, 1);
if (rezultat != 0){
return rezultat;
}
rezultat = CheckRowsOrCols(board, 0);
if (rezultat != 0){
return rezultat;
}
for (int i = 0; i < 6; i++){
rezultat = CheckDiagonals(board, i, 0, 1);
if (rezultat != 0){
return rezultat;
}
}
for (int j = 0; j < 7; j++){
rezultat = CheckDiagonals(board, 5, j, 1);
if (rezultat != 0){
return rezultat;
}
rezultat = CheckDiagonals(board, 5, j, 0);
if (rezultat != 0){
return rezultat;
}
}
for (int i = 0; i < 6; i++){
rezultat = CheckDiagonals(board, i, 6, 0);
if (rezultat != 0){
return rezultat;
}
}
return 0;
}
void SaveGame(char board[6][7], int movesPlayed, char player1Name[20], char player2Name[20]){
printf("\n\n\nEnter ID for your game: ");
int id;
scanf("%d", &id);
GameState state;
state.id = id;
for (int i = 0; i < 6; i++){
for (int j = 0; j < 7; j++){
state.board[i][j] = board[i][j];
}
}
state.numberOfMoves = movesPlayed;
strcpy(state.player1Name, player1Name);
strcpy(state.player2Name, player2Name);
FILE *filePointer;
filePointer = fopen("SavedGames.dat", "ab");
if (filePointer == NULL){
printf("\nGames not found!");
return;
}
fwrite(&state, sizeof(state), 1, filePointer);
fclose(filePointer);
printf("\nGame with ID:%d saved!", id);
}
int MakeMove(char board[6][7], int movesPlayed, char player1Name[20], char player2Name[20]) {
char sign = 'X';
if (movesPlayed % 2 == 1){
sign = 'O';
}
int column;
while (1){
printf("\nChoose the column player %c(0 for save and exit): ", sign);
column;
scanf("%d", &column);
if (column >= 0 && column <= 7 && board[0][column-1] == ' '){
break;
}
printf("\nMove not allowed!\n");
}
if (column != 0){
for (int i = 6; i >= 0; i--) {
if (board[i][column-1] == ' ') {
board[i][column-1] = sign;
printf("\n\n\n");
break;
}
}
}else {
SaveGame(board, movesPlayed, player1Name, player2Name);
return 1;
}
return 0;
}
void PlayGame(char board[6][7], char player1Name[20], char player2Name[20], int movesPlayed){
while (1){
PrintBoard(board);
if (MakeMove(board, movesPlayed, player1Name, player2Name) == 1){
break;
}
movesPlayed++;
int result = CheckForWinner(board);
if (result != 0){
PrintBoard(board);
if (result == 1){
printf("\nX wins\n\n\n");
} else {
printf("\nO wins\n\n\n");
}
break;
}
if (movesPlayed == 42){
PrintBoard(board);
printf("\nTie!\n\n\n");
break;
}
}
}
void ListAllSavedGames(){
FILE *filePointer;
filePointer = fopen("SavedGames.dat", "rb");
if (filePointer == NULL){
printf("\nGames not played yet!");
return;
}
GameState state;
while(fread(&state, sizeof(state), 1, filePointer) == 1){
printf("\n%d, X: %s, O: %s, %d", state.id, state.player1Name, state.player2Name, (42 - state.numberOfMoves));
}
fclose(filePointer);
}
void ListAllPlayerGames(){
char playerName[20];
printf("\nName of player: ");
scanf("%s", playerName);
FILE *filePointer;
filePointer = fopen("SavedGames.dat", "rb");
if (filePointer == NULL){
printf("\nGames not played yet!");
return;
}
GameState state;
while(fread(&state, sizeof(state), 1, filePointer) == 1){
if (strcmp(playerName, state.player1Name) == 0 || strcmp(playerName, state.player2Name) == 0){
printf("\n%d, X: %s, O: %s, %d", state.id, state.player1Name, state.player2Name, (42 - state.numberOfMoves));
}
}
fclose(filePointer);
}
int ShowTheBoard(){
int ID;
printf("\nEnter ID: ");
scanf("%d", &ID);
FILE *filePointer;
filePointer = fopen("SavedGames.dat", "rb");
if (filePointer == NULL){
printf("\nGames not played yet!");
return;
}
int IDfound = 0;
GameState state;
while(fread(&state, sizeof(state), 1, filePointer) == 1){
if (ID == state.id){
IDfound = 1;
printf("\nX: %s, O: %s", state.player1Name, state.player2Name);
PrintBoard(state.board);
}
}
fclose(filePointer);
if (IDfound == 0){
return 1;
}
return 0;
}
int LoadAGame(){
int ID;
printf("\nEnter ID: ");
scanf("%d", &ID);
FILE *filePointer;
filePointer = fopen("SavedGames.dat", "rb");
if (filePointer == NULL){
printf("\nGames not played yet!");
return;
}
int IDfound = 0;
GameState state;
while(fread(&state, sizeof(state), 1, filePointer) == 1){
if (ID == state.id){
IDfound = 1;
PlayGame(state.board, state.player1Name, state.player2Name, state.numberOfMoves);
}
}
fclose(filePointer);
if (IDfound == 0){
return 1;
}
return 0;
}
void ShowLoadMenu(){
int returnToMainMenu = 0;
while (returnToMainMenu == 0){
printf("\n\n\n1. List all saved games\n");
printf("2. List all saved games for a particular player\n");
printf("3. Show the board of one of the saved games\n");
printf("4. Load a game\n");
printf("5. Return to main menu\n");
printf("Choose: ");
int choice;
scanf("%d", &choice);
switch(choice){
case 1:
ListAllSavedGames();
break;
case 2:
ListAllPlayerGames();
break;
case 3:
while (ShowTheBoard() == 1){
printf("ID not valid!");
}
break;
case 4:
while (LoadAGame() == 1){
printf("ID not valid!");
}
returnToMainMenu = 1;
break;
case 5:
returnToMainMenu = 1;
break;
default:
printf("Wrong choice, try again!");
}
}
}
int main(){
int endOfProgram = 0;
while (endOfProgram == 0){
char board[6][7];
char player1Name[20];
char player2Name[20];
int movesPlayed = 0;
ShowMenu();
int choice;
scanf("%d", &choice);
switch(choice){
case 1:
ClearBoard(board);
ReadPlayerNames(player1Name, player2Name);
PlayGame(board, player1Name, player2Name, movesPlayed);
break;
case 2:
ShowLoadMenu();
break;
case 3:
printf("Goodbye!");
endOfProgram = 1;
break;
default:
printf("Wrong choice, try again!");
}
}
}
Culprit is likely to be inside MakeMove:
if (column >= 0 && column <= 7 && board[0][column-1] == ' ') {
break;
}
if you pass 0 as column, the first 2 tests will indeed succeed (both 0 >= 0 and 0 <= 7 are true). But third one tries to use board[0][-1]. -1 is not a valid index and you are invoking UB.
If column is 0, you should not test anything else, so your test should be:
if (column == 0 || (column > 0 && column <= 7
&& board[0][column-1] == ' ')) {
break;
}
I made a program which changes infix notation to postfix notation with using stack in C.
I made a function which prints the result of the postfix notation(from infix notaton).
But, the result of a notation is wrong. This should be '195' but its result is '-61'.
The results of the other notations are right but only the notation(op2) has this problem.
What should I do to fix this problem?
This is my code:
typedef char element;
typedef struct {
element stack[MAX_STACK_SIZE];
int top;
} StackType;
void init(StackType *s) {
s->top = -1;
}
int is_empty(StackType *s) {
return (s->top == -1);
}
int is_full(StackType *s) {
return (s->top == (MAX_STACK_SIZE - 1));
}
void push(StackType *s, element item) {
if (is_full(s)) {
fprintf(stderr, "FULL STACK ERROR\n");
return;
}
else s->stack[++(s->top)] = item;
}
element pop(StackType *s) {
if (is_empty(s)) {
fprintf(stderr, "EMPTY STACK ERROR\n");
exit(1);
}
else return s->stack[(s->top)--];
}
int eval(char exp[]) {
int op1, op2, value, i = 0;
int len = strlen(exp);
char ch;
StackType s;
init(&s);
for (i = 0; i < len; i++) {
ch = exp[i];
if (ch != '+' && ch != '-' && ch != '*' && ch != '/') {
value = ch - '0';
push(&s, value);
}
else {
op2 = pop(&s);
op1 = pop(&s);
switch (ch) {
case '+': push(&s, op1 + op2); break;
case '-': push(&s, op1 - op2); break;
case '*': push(&s, op1 * op2); break;
case '/': push(&s, op1 / op2); break;
}
}
}
return pop(&s);
}
char* infix_to_postfix(char exp[]) {
int i = 0, j = 0;
char ch, top_op;
int len = strlen(exp);
char *ex = (char *)malloc(sizeof(char)*(len + 1));
StackType s;
init(&s);
for (i = 0; i < len; i++) {
ch = exp[i];
switch (ch) {
case '+': case '-': case '*': case '/':
while (!is_empty(&s) && (prec(ch) <= prec(peek(&s)))) {
ex[j++] = pop(&s);
}
push(&s, ch);
break;
case '(':
push(&s, ch);
break;
case ')':
top_op = pop(&s);
while (top_op != '(') {
ex[j++] = top_op;
top_op = pop(&s);
}
break;
default:
ex[j++] = ch;
break;
}
}
while (!is_empty(&s)) {
ex[j++] = pop(&s);
}
ex[j] = NULL;
return ex;
}
void main() {
char *op1 = "(9-(3+2))*3+4*((4+2)/3)-1";
char *op2 = "(4*5-3)/3+((2+5*7)-8+9)*5";
char *op3 = "7*3-7-4+1/3+6-8*2";
char *pos1, *pos2, *pos3;
pos1 = infix_to_postfix(op1);
pos2 = infix_to_postfix(op2);
pos3 = infix_to_postfix(op3);
printf(" Result : %d\n", eval(pos1));
printf(" Result : %d\n", eval(pos2));
printf(" Result : %d\n", eval(pos3));
}
[RESULT]
Result : 19
Result : -61 // This should be '195'.
Result : 0
The clue is 61+195 = 256. Which means that somewhere, your computations are being saved to chars. Looks like it is element.
typedef element int;
I am having a problem storing data it seems in some buffers that I have made. Here is how the code looks:
Here are the definitions for each function:
WriteKeyBrdNum:
char Write_Keyboard::WriteKeybrdNum(TSPoint pos, Data_Buffers dB, int selection, int count)
{
char data;
switch (selection)
{
case EXERCISE:
{
if (pos.y > GRABCHARSIZE * 9) //0
{
//dspWord[count] = '0';
dB.SetDataBufferChar('0', selection, count);
data = dB.GetDataBufferChar(selection, count);
}
else if (pos.y > GRABCHARSIZE * 8) //1
{
//dspWord[count] = '1';
dB.SetDataBufferChar('1', selection, count);
data = dB.GetDataBufferChar(selection, count);
//data = '1';
}
else if (pos.y > GRABCHARSIZE * 7) //2
{
//dspWord[count] = '2';
dB.SetDataBufferChar('2', selection, count);
data = dB.GetDataBufferChar(selection, count);
//data = '2';
}
else if (pos.y > GRABCHARSIZE * 6) //3
{
//dspWord[count] = '3';
dB.SetDataBufferChar('3', selection, count);
data = dB.GetDataBufferChar(selection, count);
//data = '3';
}
else if (pos.y > GRABCHARSIZE * 5) //4
{
//dspWord[count] = '4';
dB.SetDataBufferChar('4', selection, count);
data = dB.GetDataBufferChar(selection, count);
//data = '4';
}
else if (pos.y > GRABCHARSIZE * 4) //5
{
//dspWord[count] = '5';
dB.SetDataBufferChar('5', selection, count);
data = dB.GetDataBufferChar(selection, count);
//data = '5';
}
else if (pos.y > GRABCHARSIZE * 3) //6
{
//dspWord[count] = '6';
dB.SetDataBufferChar('6', selection, count);
data = dB.GetDataBufferChar(selection, count);
//data = '6';
}
else if (pos.y > GRABCHARSIZE * 2) //7
{
//dspWord[count] = '7';
dB.SetDataBufferChar('7', selection, count);
data = dB.GetDataBufferChar(selection, count);
//data = '7';
}
else if (pos.y > GRABCHARSIZE) //8
{
//dspWord[count] = '8';
dB.SetDataBufferChar('8', selection, count);
data = dB.GetDataBufferChar(selection, count);
//data = '8';
}
else if (pos.y > 0) //9
{
//dspWord[count] = '9';
dB.SetDataBufferChar('9', selection, count);
data = dB.GetDataBufferChar(selection, count);
//data = '9';
}
return data;
break;
}
GetDataBufferChar:
char Data_Buffers::GetDataBufferChar(int bufferSelect, int count)
{
char letter;
switch (bufferSelect)
{
case EXERCISE:
{
letter = dspWord[count];
break;
}
case SETS:
{
letter = setsNum[count];
break;
}
case REPS:
{
letter = repsNum[count];
break;
}
case WEIGHT:
{
letter = weightNum[count];
break;
}
default:
{
letter = '\0';
break;
}
}
return letter;
}
SetDataBufferChar:
void Data_Buffers::SetDataBufferChar(char data, int bufferSelect, int count)
{
switch (bufferSelect)
{
case EXERCISE:
{
dspWord[count] = data;
break;
}
case SETS:
{
setsNum[count] = data;
break;
}
case REPS:
{
repsNum[count] = data;
break;
}
case WEIGHT:
{
weightNum[count] = data;
break;
}
default:
break;
}
}
DrawBufferChar:
char Draw_Stuff::DrawBufferChar(SWTFT tft, Data_Buffers dB, int selection, int count, int charSpace)
{
char data;
data = dB.GetDataBufferChar(selection, count);
tft.drawChar(TEXTXPOS*charSpace, TEXTYPOS + 30, data, BLACK, WHITE, EXTTEXTSIZE);
return data;
}
Main loop:
dspWord[wordCount] = writeKeyboard.WriteKeybrdNum(p, dataBuffer, selection, wordCount);
Serial.print("data\t"); Serial.println(dspWord[wordCount]);// Serial.print("\n");
dspWord[wordCount] = drawStuff.DrawBufferChar(tft, dataBuffer, selection, wordCount, wordSpace);
Serial.print("data1\t"); Serial.println(dspWord[wordCount]); //Serial.print("\n");
The Get and Set functions are storing data and getting data from buffers that are established as private buffers in Data_buffers class. The whole point is to be able to set these data buffers in one function, and get them using another function. For the first serial print, the data that is being set in the WriteKeybrdNum function is actually displayed. Then when I call DrawBufferChar, the second serial port print has no data. Am I missing something here. Both DrawBufferChar and WriteKeybrdNum are calling the exact same GetDataBufferChar function with the same "selection" and same "wordCount" yet data is being returned in one function and not the other. Doesn't make sense to me.
Any Help would be greatly appreciated.
Thanks.