Struct/Malloc or Other? SIGSEGV Error - c

I have debugged and watched my "watch window" to get an idea where the problem was. It does not even finish the code though. During the test sequence to find the user inputted word, it fails. It has a SIGSEGV fault at the found function.
The code is meant to take in a word puzzle and then allow the user to find the words.
puzzleInput.txt:
M,N,O,S,L,I,W,E,R,E,L,Y,T,L,E,A,G,N
A,H,O,O,V,E,R,T,A,Y,L,O,R,V,E,N,N,A
D,F,D,R,O,O,S,E,V,E,L,T,O,N,O,M,I,M
I,N,T,P,M,H,I,E,G,D,I,L,O,O,C,O,D,U
S,O,N,L,I,J,Q,A,D,A,M,S,S,R,N,N,R,R
O,X,L,O,G,E,F,F,M,O,I,R,E,E,G,R,A,T
N,I,B,T,S,O,R,A,O,R,M,O,V,A,W,O,H,N
F,N,H,U,R,R,B,C,R,N,L,R,E,G,B,E,W,E
R,O,S,D,C,O,E,A,E,I,O,N,L,A,U,A,J,R
K,W,U,N,L,H,H,F,N,I,O,S,T,N,S,W,A,U
E,R,B,A,J,B,A,C,F,S,S,M,N,H,H,R,D,B
N,E,W,L,O,T,O,N,K,E,C,E,I,H,T,H,A,N
N,T,H,E,H,L,A,C,A,K,J,N,N,H,O,I,M,A
E,R,G,V,N,C,A,F,I,N,G,H,U,H,A,J,S,V
D,A,R,E,S,J,C,N,T,T,A,R,N,B,O,Y,A,E
Y,C,A,L,O,D,L,N,O,S,I,R,R,A,H,W,E,O
N,E,N,C,N,E,T,N,N,O,T,N,I,L,C,O,E,S
D,A,T,Y,Y,P,O,L,K,G,A,R,F,I,E,L,D,R
enter code here
code:
/* This program reads a puzzle from a file
and allows the user to define a word which
they want to find in the word puzzle.*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
void fileNam(char[]);
char showMenu();
int fileData(char*);
void alphaArray();
void getUser();
void fileError(char*);
void findUserFirst();
int createString();
void found(int);
void notFound(char*);
void goToExit();
void display();
struct alphabet
{
int *A;int *B; int *C; int *D; int *E; int *F;
int *G; int *H; int *I; int *J; int *K; int *L; int *M;
int *N; int *O; int *P; int *Q; int *R; int *S;
int *T; int *U; int *V; int *W; int *X; int *Y; int *Z;
int a; int b; int c; int d; int e; int f; int g; int h; int i; int j; int k; int l; int m;
int n; int o; int p; int q; int r; int s; int t; int u; int v; int w; int x; int y; int z;
}fill;
struct user
{
struct alphabet* ptr;
int *attempt;
int testNum;
int columns;
int rows;
int userSize;
int puzzleSize;
char *puzzleArray;
char userWord[45];
}test;
int main()
{
int wordsFound = 0;
int fileErr = 0;
int wordF = 0;
char option;
char fileLoc[100] = {0};
do
{
fflush(stdin);
option = showMenu();
fflush(stdin);
if(fileErr == -1)
{
fileError(fileLoc);
}
switch(option)
{
case 'a':;
fileNam(fileLoc);
strcat(fileLoc,"\\puzzleInput.txt");
fileErr = fileData(fileLoc);
break;
case 'b':
display();
break;
case 'c':
getUser();
findUserFirst();
wordF = 0;
do{
wordF = createString();
if(wordF > 0)
{
found(wordF);
wordsFound++;
}
else
{
test.ptr;
}
}while(*test.attempt <= test.testNum);
if(wordF < -1)
notFound(fileLoc);
break;
case 'd':
goToExit(wordsFound);
break;
default:
printf("Invalid selection.\nPlease choose again.\n");
break;
}
}while(option != 'd');
return 0;
}
char showMenu()
{
char option;
printf("Choose one of the following:\n");
printf("\ta. Enter file location(full path)\n");
printf("\tb. Display the puzzle\n");
printf("\tc. Find a word\n");
printf("\td. Exit\n");
option = getchar();
return option;
}
void goToExit(int found)
{
printf("\nYou found %d words!\n", found);
if(found > 5)
{
printf("Awesome job! Come back to play again!");
}
else{
printf("Better luck next time!");
}
printf("Press any key to close window.");
getchar();
free(fill.A);free(fill.B); free(fill.C); free(fill.D); free(fill.E); free(fill.F);
free(fill.G); free(fill.H); free(fill.I); free(fill.J); free(fill.K); free(fill.L); free(fill.M);
free(fill.N); free(fill.O); free(fill.P); free(fill.Q); free(fill.R); free(fill.S);
free(fill.T); free(fill.U); free(fill.V); free(fill.W); free(fill.X); free(fill.Y); free(fill.Z);
free(test.puzzleArray);
}
void display()
{
int i, j, k = 0;
for(i=0; i <= test.columns; i++)
{
for(j=0; j <= test.rows; j++)
{
printf("%c, ", test.puzzleArray[k]);
k++;
}
printf("\n");
}
}
void fileNam(char fileLoc[])
{
printf("When entering file location, do not \n");
printf("include the file name.\nLOCATION:\n");
gets(fileLoc);
}
void fileError(char* fileName)
{
printf("There was an error with the file location");
printf(" that you typed in.\nPlease make sure file ");
printf("location and name are correct.\nIf name is wrong, ");
printf("please change the name of your file to match.\n");
printf("FILE LOCATION AND NAME: \"%s\"\n\n", fileName);
}
int fileData(char* fname)
{
int i = 0;
char curr;
FILE * fPtr;
fPtr = fopen(fname, "r");
char buffer[1000] = {0};
if(fPtr == NULL)//test if file opened
{
printf("There has been an error in opening %s!\n", fname);
return -1;
}
while (!feof(fPtr))
{
fgets(buffer, 1000, fPtr);
test.rows++;
}
rewind(fPtr);
while(fgetc(fPtr) >= 65 && fgetc(fPtr) <= 90)
{
test.puzzleSize++;
}
test.puzzleArray = (char*) malloc((test.puzzleSize) * sizeof(char));
printf("%d", test.puzzleSize);
rewind(fPtr);
i = 0;
while ((curr = fgetc(fPtr)) != EOF)
{
if(curr == ',' || curr == '\n')
{
if(curr == '\n')
test.columns++;
}
if(curr >= 65 && curr <= 90)
{
test.puzzleArray[i] = curr;
i++;
}
}
fclose(fPtr);
alphaArray();
return 0;
}
void alphaArray()
{
int i = 0;
char current = 0;
while(test.puzzleArray[i] != '\0')
{
current = test.puzzleArray[i];
switch(tolower(current))//accidentally coded lowercase, quick fix
{
case 'a':
fill.a++;
break;
case 'b':
fill.b++;
break;
case 'c':
fill.c++;
break;
case 'd':
fill.d++;
break;
case 'e':
fill.e++;
break;
case 'f':
fill.f++;
break;
case 'g':
fill.g++;
break;
case 'h':
fill.h++;
break;
case 'i':
fill.i++;
break;
case 'j':
fill.j++;
break;
case 'k':
fill.k++;
break;
case 'l':
fill.l++;
break;
case 'm':
fill.m++;
break;
case 'n':
fill.n++;
break;
case 'o':
fill.o++;
break;
case 'p':
fill.p++;
break;
case 'q':
fill.q++;
break;
case 'r':
fill.r++;
break;
case 's':
fill.s++;
break;
case 't':
fill.t++;
break;
case 'u':
fill.u++;
break;
case 'v':
fill.v++;
break;
case 'w':
fill.w++;
break;
case 'x':
fill.x++;
break;
case 'y':
fill.y++;
break;
case 'z':
fill.z++;
break;
default: printf("\n");
break;
}
i++;
}
fill.A = (int *)malloc(sizeof(int)*fill.a); fill.B = (int *)malloc(sizeof(int)*fill.b);
fill.C = (int *)malloc(sizeof(int)*fill.c); fill.D = (int *)malloc(sizeof(int)*fill.d);
fill.E = (int *)malloc(sizeof(int)*fill.e); fill.F = (int *)malloc(sizeof(int)*fill.f);
fill.G = (int *)malloc(sizeof(int)*fill.g); fill.H = (int *)malloc(sizeof(int)*fill.h);
fill.I = (int *)malloc(sizeof(int)*fill.i); fill.J = (int *)malloc(sizeof(int)*fill.j);
fill.K = (int *)malloc(sizeof(int)*fill.k); fill.L = (int *)malloc(sizeof(int)*fill.l);
fill.M = (int *)malloc(sizeof(int)*fill.m); fill.N = (int *)malloc(sizeof(int)*fill.n);
fill.O = (int *)malloc(sizeof(int)*fill.o); fill.P = (int *)malloc(sizeof(int)*fill.p);
fill.Q = (int *)malloc(sizeof(int)*fill.q); fill.R = (int *)malloc(sizeof(int)*fill.r);
fill.S = (int *)malloc(sizeof(int)*fill.s); fill.T = (int *)malloc(sizeof(int)*fill.t);
fill.U = (int *)malloc(sizeof(int)*fill.u); fill.V = (int *)malloc(sizeof(int)*fill.v);
fill.W = (int *)malloc(sizeof(int)*fill.w); fill.X = (int *)malloc(sizeof(int)*fill.x);
fill.Y = (int *)malloc(sizeof(int)*fill.y); fill.Z = (int *)malloc(sizeof(int)*fill.z);
fill.a = 0;fill.b =0; fill.c =0; fill.d =0; fill.e =0; fill.f =0;
fill.g =0; fill.k =0; fill.o =0; fill.s =0; fill.w =0;
fill.h =0; fill.l =0; fill.p =0; fill.t =0; fill.x =0;
fill.i =0; fill.m =0; fill.q =0; fill.u =0; fill.y =0;
fill.j =0; fill.n =0; fill.r =0; fill.v =0; fill.z =0;
i = 0;
while(test.puzzleArray[i] != '\0')
{
current = test.puzzleArray[i];
switch(tolower(current))//accidentally coded lowercase, quick fix
{
case 'a':
fill.A[fill.a] = i;
fill.a++;
break;
case 'b':
fill.B[fill.b] = i;
fill.b++;
break;
case 'c':
fill.C[fill.c] = i;
fill.c++;
break;
case 'd':
fill.D[fill.d] = i;
fill.d++;
break;
case 'e':
fill.E[fill.e] = i;
fill.e++;
break;
case 'f':
fill.F[fill.f] = i;
fill.f++;
break;
case 'g':
fill.G[fill.g] = i;
fill.g++;
break;
case 'h':
fill.H[fill.h] = i;
fill.h++;
break;
case 'i':
fill.I[fill.i] = i;
fill.i++;
break;
case 'j':
fill.J[fill.j] = i;
fill.j++;
break;
case 'k':
fill.K[fill.k] = i;
fill.k++;
break;
case 'l':
fill.L[fill.l] = i;
fill.l++;
break;
case 'm':
fill.M[fill.m] = i;
fill.m++;
break;
case 'n':
fill.N[fill.n] = i;
fill.n++;
break;
case 'o':
fill.O[fill.o] = i;
fill.o++;
break;
case 'p':
fill.P[fill.p] = i;
fill.p++;
break;
case 'q':
fill.Q[fill.q] = i;
fill.q++;
break;
case 'r':
fill.R[fill.r] = i;
fill.r++;
break;
case 's':
fill.S[fill.s] = i;
fill.s++;
break;
case 't':
fill.T[fill.t] = i;
fill.t++;
break;
case 'u':
fill.U[fill.u] = i;
fill.u++;
break;
case 'v':
fill.V[fill.v] = i;
fill.v++;
break;
case 'w':
fill.W[fill.w] = i;
fill.w++;
break;
case 'x':
fill.X[fill.x] = i;
fill.x++;
break;
case 'y':
fill.Y[fill.y] = i;
fill.y++;
break;
case 'z':
fill.Z[fill.z] = i;
fill.z++;
break;
default: printf("\n");
break;
}
i++;
}
}
void getUser()
{
test.testNum = 0;
test.userWord[45] = '\0';
test.ptr = 0;
printf("\nWhat word would you like to search for?\n");
scanf("%s", test.userWord);
test.userSize = strlen(test.userWord);
}
void findUserFirst()
{
switch(tolower(test.userWord[0]))
{
case 'a':
test.attempt = &fill.A[0];
test.testNum = fill.a;
break;
case 'b':
test.attempt = &fill.B[0];
test.testNum = fill.b;
break;
case 'c':
test.attempt = &fill.C[0];
test.testNum = fill.c;
break;
case 'd':
test.attempt = &fill.D[0];
test.testNum = fill.d;
break;
case 'e':
test.attempt = &fill.E[0];
test.testNum = fill.e;
break;
case 'f':
test.attempt = &fill.F[0];
test.testNum = fill.f;
break;
case 'g':
test.attempt = &fill.G[0];
test.testNum = fill.g;
break;
case 'h':
test.attempt = &fill.H[0];
test.testNum = fill.h;
break;
case 'i':
test.attempt = &fill.I[0];
test.testNum = fill.i;
break;
case 'j':
test.attempt = &fill.J[0];
test.testNum = fill.j;
break;
case 'k':
test.attempt = &fill.K[0];
test.testNum = fill.k;
break;
case 'l':
test.attempt = &fill.L[0];
test.testNum = fill.l;
break;
case 'm':
test.attempt = &fill.M[0];
test.testNum = fill.m;
break;
case 'n':
test.attempt = &fill.N[0];
test.testNum = fill.n;
break;
case 'o':
test.attempt = &fill.O[0];
test.testNum = fill.o;
break;
case 'p':
test.attempt = &fill.P[0];
test.testNum = fill.p;
break;
case 'q':
test.attempt = &fill.Q[0];
test.testNum = fill.q;
break;
case 'r':
test.attempt = &fill.R[0];
test.testNum = fill.r;
break;
case 's':
test.attempt = &fill.S[0];
test.testNum = fill.s;
break;
case 't':
test.attempt = &fill.T[0];
test.testNum = fill.t;
break;
case 'u':
test.attempt = &fill.U[0];
test.testNum = fill.u;
break;
case 'v':
test.attempt = &fill.V[0];
test.testNum = fill.v;
break;
case 'w':
test.attempt = &fill.W[0];
test.testNum = fill.w;
break;
case 'x':
test.attempt = &fill.X[0];
test.testNum = fill.x;
break;
case 'y':
test.attempt = &fill.Y[0];
test.testNum = fill.y;
break;
case 'z':
test.attempt = &fill.Z[0];
test.testNum = fill.z;
break;
default: printf("\n");
}
}
int createString()
{
int i = 0, upRoom = 0, rightRoom = 0;
int leftRoom = 0, downRoom = 0;
int columnPos = 0, rowPos = 0;
int arPos = 0;
int moveup = 0, moveupr = 0;
int moveupl = 0, mover = 0;
int movel = 0, moved = 0;
int movedr = 0, movedl = 0;
char up[45];
char upRight[45];
char right[45];
char downRight[45];
char down[45];
char downLeft[45];
char left[45];
char upLeft[45];
arPos = *test.attempt;
columnPos = arPos / test.columns;
rowPos = arPos % test.rows;
upRoom = test.columns/2 - columnPos;
downRoom = test.columns/2 - columnPos;
rightRoom = test.rows/2 - rowPos;
leftRoom = test.rows/2 - rowPos;
moveup = -(test.rows);
moveupr = (test.rows - 1) * (-1),
moveupl = -(test.rows + 1);
mover = 1;
movel = 1;
moved = test.rows,
movedr = 1 * (test.rows + 1);
movedl = 1 * (test.rows - 1);
for(i=0; i < test.userSize; i++)
{
if(rightRoom >= 0)
{
right[i] = test.puzzleArray[arPos + i*mover];
if(upRoom >= 0)
upRight[i] = test.puzzleArray[arPos + i*moveupr];
if(downRoom >= 0)
downRight[i] = test.puzzleArray[arPos + i*movedr];
}
if(leftRoom >= 0)
{
left[i] = test.puzzleArray[arPos - movel];
if(upRoom >= 0)
upLeft[i] = test.puzzleArray[arPos + i*moveupl];
if(downRoom >= 0)
downLeft[i] = test.puzzleArray[arPos + i*movedl];
}
if(upRoom >= 0)
up[i] = test.puzzleArray[arPos + i*moveup];
if(downRoom >= 0)
down[i] = test.puzzleArray[arPos + i*moved];
}
for(i = 0; i < test.userSize; i++)
{
if(strcmp(up, test.userWord) == 0)
return 1;
if(strcmp(upRight, test.userWord) == 0)
return 2;
if(strcmp(right, test.userWord) == 0)
return 3;
if(strcmp(downRight, test.userWord) == 0)
return 4;
if(strcmp(down, test.userWord) == 0)
return 5;
if(strcmp(downLeft, test.userWord) == 0)
return 6;
if(strcmp(left, test.userWord) == 0)
return 7;
if(strcmp(upLeft, test.userWord) == 0)
return 8;
else
return -1;
}
return -1;
}
void found(int style)
{
int pos = 0, movement = 0;
int i, j, k = 0;
char *cpyPuzzle;
cpyPuzzle = (char*) malloc((test.puzzleSize) * sizeof(char));
strcpy(cpyPuzzle, test.puzzleArray);
switch(style){
case 1:
movement = test.rows;
break;
case 2:
movement = test.rows - 1;
break;
case 3:
movement = 1;
break;
case 4:
movement = test.rows + 1;
break;
case 5:
movement = test.rows;
break;
case 6:
movement = test.rows - 1;
break;
case 7:
movement = 1;
break;
case 8:
movement = test.rows + 1;
break;
}
for(i = 0; i < test.puzzleSize; i++)
{
cpyPuzzle[i] = '~';
}
for(i=0; i < test.userSize; i++)
{
pos = test.attempt + (i*movement);
cpyPuzzle[pos] = test.userWord[i];
}
for(i=0; i < test.columns; i++)
{
for(j=0; j < test.rows; j++)
{
printf("%c, ", cpyPuzzle[k]);
k++;
}
printf("\n");
}
free(cpyPuzzle);
}
void notFound(char *fileN)
{
printf("In file %s %c was not found.\n", test.userWord, fileN);
printf("You can try finding another word");
printf(" by pressing the option to show puzzle and\n");
printf("then the option to find a word, once you've found one.\n");
}

(Posted on behalf of the OP).
SOLVED! - the error was I was not dereferencing and then referencing a pointer.

Related

Segmentation fault on assigning int

I am following the video series "Coding a Rogue/Nethack clone in c" and getting a segfault despite the fact that the creator isn't.
This is using ncurses and the menu library.
gdb says it's in the function handleInput, when I try to set the x and y.
Pos* handleInput(int input, Player* user) {
Pos * newPosition;
newPosition = malloc(sizeof(Pos));
switch (input)
{
/* move up */
case 'w':
case 'W':
newPosition->y = user->pos->y - 1;
newPosition->x = user->pos->x;
break;
/* move down */
case 's':
case 'S':
newPosition->y = user->pos->y + 1;
newPosition->x = user->pos->x;
break;
/* move left */
case 'a':
case 'A':
newPosition->y = user->pos->y;
newPosition->x = user->pos->x - 1;
break;
/* move right */
case 'd':
case 'D':
newPosition->y = user->pos->y; // Segfault here
newPosition->x = user->pos->x + 1;
default:
break;
Some typedefs:
typedef struct Level {
int level;
char** tiles;
int numRooms;
struct Player* user;
struct Room** room;
struct Monster** Mons;
int numMons;
} Level;
typedef struct Pos {
int x;
int y;
} Pos;
typedef struct Player {
Pos* pos;
int atk;
int maxHP;
int xp;
int gold;
int health;
} Player;
typedef struct Monster {
char string[2];
char symbol;
int alive;
int health;
int attack;
int speed;
int defense;
int pathfinding;
Pos* pos;
} Monster;
And my game function:
int gameLoop()
{
int ch;
Pos* newPosition;
Level * level;
level = createLevel(1);
Player* user = level->user;
printGameHud(level);
/* main game loop */
while ((ch = getch()) != 'q')
{
printGameHud(level);
newPosition = handleInput(ch, user);
checkPosition(newPosition, level);
moveMonster(level);
move(level->user->pos->y, level->user->pos->x);
if (level->user->health <= 0)
{
return -1;
}
}
return 1;
}
Finally, my menu function, which seems to be where this started:
void menuLoop () {
int choice;
while (true) {
char* choices[] = {"Start", "Exit"};
choice = mainMenu(2, choices);
switch (choice) {
case START_GAME:
gameLoop();
clear();
break;
case QUIT_GAME:
return;
}
}
}
int closeMenu(int numItems, MENU* menu, ITEM** items){
unpost_menu(menu);
free_menu(menu);
for (int i = 0; i < numItems; i++) {
free_item(items[i]);
}
return 1;
}
int mainMenu(int numItems, char* items[]) {
int c, i, value;
MENU* menu;
ITEM* current;
ITEM** menuItems = malloc(sizeof(**menuItems) * numItems);
for (i = 0; i < numItems; i++) {
menuItems[i] = new_item(items[i], "");
}
menuItems[i] = (ITEM*)NULL;
menu = new_menu((ITEM**)menuItems);
post_menu(menu);
refresh();
while (true) {
c = getch();
switch(c){
case KEY_DOWN:
menu_driver(menu, REQ_DOWN_ITEM);
break;
case KEY_UP:
menu_driver(menu, REQ_UP_ITEM);
break;
case 10:
current = current_item(menu);
value = item_index(current);
closeMenu(numItems, menu, menuItems);
return value;
}
}
}

Convert a string from argv to unsigned byte array

For example i need an
unsigned code[] {
0x0001,
0x0002,
0x0003,
.. and so on
}
from argv. I would like to input it as a stream like this:
000100020003 and so on
unsigned hextodigit(int hex)
{
unsigned result = 0;
switch(toupper(hex))
{
case '0':
return 0;
break;
case '1':
return 1;
break;
case '2':
return 2;
break;
case '3':
return 3;
break;
case '4':
return 4;
break;
case '5':
return 5;
break;
case '6':
return 6;
break;
case '7':
return 7;
break;
case '8':
return 8;
break;
case '9':
return 9;
break;
case 'A':
return 10;
break;
case 'B':
return 11;
break;
case 'C':
return 12;
break;
case 'D':
return 13;
break;
case 'E':
return 14;
break;
case 'F':
return 15;
break;
default:
break;
}
}
unsigned fromhex4chars(const char *str)
{
return hextodigit(*(str + 3)) + (hextodigit(*(str + 2)) << 4) + (hextodigit(*(str + 1)) << 8) + (hextodigit(*str) << 12);
}
void convert(const char *str, unsigned *buff)
{
size_t len = strlen(str) / 4;
while(len--)
{
*buff++ = fromhex4chars(str);
str += 4;
}
}
int main(int argc, char **argv)
{
unsigned x[100];
convert(argv[1], x);
return 0;
}

how to switch between players with enum from .h?

Does anyone know why when I run this code it goes for P2_TURN and how to make this enum active that when P2 move then P1 goes and whoever win the correct statement will be given from print_status()… also is there an easier/cleaner way to assign the winner. At the void process_move(struct game* p_game_info) is there a way to replace digits 0-8 with user input without switch case….Sorry for being a bit chaotic with this query but it’s almost 4 in the morning so hope you’ll forgive me….
game.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "game.h"
void play_game()
{
struct game *p_game_info = 0;
p_game_info = malloc(sizeof(struct game));
initialise_game (p_game_info, "John", "Annie");
draw_banner();
display_board(p_game_info->board);
system("cls");
display_board_positions ();
draw_banner();
process_move( p_game_info);
display_board(p_game_info->board);
print_status ( p_game_info );
}
void initialise_game(struct game* p_game_info, char* name1, char* name2)
{
for (int r=0; r<3; r++)
for(int c=0; c<3; c++)
p_game_info->board[r][c] = SPACE;
display_board_positions ();
p_game_info->status=P1_TURN;
// p_game_info->finished = False;
strncpy(p_game_info->playerNames[0], name1,MAX_NAME_LEN);
strncpy(p_game_info->playerNames[1], name2,MAX_NAME_LEN);
}
void draw_banner(){
printf("---------------\n");
printf(" GAME STATUS \n");
printf("---------------\n");
}
void display_board( char board[3][3]){
printf("---------------\n");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
printf(" %c ", board[i][j]);
if (j != 2)
printf("|");
}
if (i != 2)
printf("\n-----------");
printf("\n");
}
printf("---------------\n");
}
void print_status (struct game*p_game_info ){
if ((p_game_info->finished=False)&&
(p_game_info->status=P1_TURN))
{
printf("John's Turn\n");
}
else if ((p_game_info->finished=False)&&
(p_game_info->status=P2_TURN))
{
printf("Annie's Turn\n");
}
else if
(p_game_info->status==P1_WON)
{
printf( "Well done John, you have won\n");
}
else if
(p_game_info->status==P2_WON)
{
printf("Well done Annie, you have won\n");
}
else if
(p_game_info->status==DRAW)
{
printf("Game Over It is a draw\n");
}
}
void display_board_positions (){
int count = 0;
printf("---------------\n");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
printf(" %d ", count);
count++;
if (j != 2)
printf("|");
}
if (i != 2)
printf("\n-----------");
printf("\n");
}
printf("---------------\n");
}
void process_move(struct game* p_game_info){
if (p_game_info->status==P1_TURN){
printf("enter number for 'X' from 0-8\n");
char ckey = (char) getchar();
switch (ckey){
case '0':
if(p_game_info->board[0][0]==SPACE){
p_game_info->board[0][0]=X_SYMBOL;
}
break;
case '1':
if(p_game_info->board[0][1]==SPACE){
p_game_info->board[0][1]=X_SYMBOL;
}
break;
case '2':
if(p_game_info->board[0][2]==SPACE){
p_game_info->board[0][2]=X_SYMBOL;
}
break;
case '3':
if(p_game_info->board[1][0]==SPACE){
p_game_info->board[1][0]=X_SYMBOL;
}
break;
case '4':
if(p_game_info->board[1][1]==SPACE){
p_game_info->board[1][1]=X_SYMBOL;
}
break;
case '5':
if(p_game_info->board[1][2]==SPACE){
p_game_info->board[1][2]=X_SYMBOL;
}
break;
case '6':
if(p_game_info->board[2][0]==SPACE){
p_game_info->board[2][0]=X_SYMBOL;
}
break;
case '7':
if(p_game_info->board[2][1]==SPACE){
p_game_info->board[2][1]=X_SYMBOL;
}
break;
case '8':
if(p_game_info->board[2][1]==SPACE){
p_game_info->board[2][1]=X_SYMBOL;
}
break;
default:
;
}p_game_info->status=P2_TURN
}
else if (p_game_info->status=P2_TURN){
printf("enter number for 'O' from 0-8\n");
char ckey = (char) getchar();
switch (ckey){
case '0':
if(p_game_info->board[0][0]==SPACE){
p_game_info->board[0][0]=O_SYMBOL;
}
break;
case '1':
if(p_game_info->board[0][1]==SPACE){
p_game_info->board[0][1]=O_SYMBOL;
}
break;
case '2':
if(p_game_info->board[0][2]==SPACE){
p_game_info->board[0][2]=O_SYMBOL;
}
break;
case '3':
if(p_game_info->board[1][0]==SPACE){
p_game_info->board[1][0]=O_SYMBOL;
}
break;
case '4':
if(p_game_info->board[1][1]==SPACE){
p_game_info->board[1][1]=O_SYMBOL;
}
break;
case '5':
if(p_game_info->board[1][2]==SPACE){
p_game_info->board[1][2]=O_SYMBOL;
}
break;
case '6':
if(p_game_info->board[2][0]==SPACE){
p_game_info->board[2][0]=O_SYMBOL;
}
break;
case '7':
if(p_game_info->board[2][1]==SPACE){
p_game_info->board[2][1]=O_SYMBOL;
}
break;
case '8':
if(p_game_info->board[2][1]==SPACE){
p_game_info->board[2][1]=O_SYMBOL;
}
break;
default:
;
}}
}
void finished_game(struct game* p_game_info){
if((p_game_info->board[0][0]==O_SYMBOL)&&(p_game_info->board[0] [1]==O_SYMBOL)&&(p_game_info->board[0][2]==O_SYMBOL)||
(p_game_info->board[1][0]==O_SYMBOL)&&(p_game_info->board[1][1]==O_SYMBOL)&& (p_game_info->board[1][2]==O_SYMBOL)||
(p_game_info->board[2][0]==O_SYMBOL)&&(p_game_info->board[2][1]==O_SYMBOL)&&(p_game_info->board[2][2]==O_SYMBOL)||
(p_game_info->board[0][0]==O_SYMBOL)&&(p_game_info->board[1][0]==O_SYMBOL)&&(p_game_info->board[2][0]==O_SYMBOL)||
(p_game_info->board[0][1]==O_SYMBOL)&&(p_game_info->board[1][1]==O_SYMBOL)&&(p_game_info->board[2][1]==O_SYMBOL)||
(p_game_info->board[0][2]==O_SYMBOL)&&(p_game_info->board[1][2]==O_SYMBOL)&&(p_game_info->board[2][2]==O_SYMBOL)||
(p_game_info->board[0][0]==O_SYMBOL)&&(p_game_info->board[1][1]==O_SYMBOL)&&(p_game_info->board[2][2]==O_SYMBOL)||
(p_game_info->board[0][2]==O_SYMBOL)&&(p_game_info->board[1][1]==O_SYMBOL)&&(p_game_info->board[2][0]==O_SYMBOL))
{
p_game_info->status=P2_WON;
return;
}
else if((p_game_info->board[0][0]==X_SYMBOL)&&(p_game_info->board[0][1]==X_SYMBOL)&&(p_game_info->board[0][2]==X_SYMBOL)||
(p_game_info->board[1][0]==X_SYMBOL)&&(p_game_info->board[1][1]==X_SYMBOL)&&(p_game_info->board[1][2]==X_SYMBOL)||
(p_game_info->board[2][0]==X_SYMBOL)&&(p_game_info->board[2][1]==X_SYMBOL)&&(p_game_info->board[2][2]==X_SYMBOL)||
(p_game_info->board[0][0]==X_SYMBOL)&&(p_game_info->board[1][0]==X_SYMBOL)&&(p_game_info->board[2][0]==X_SYMBOL)||
(p_game_info->board[0][1]==X_SYMBOL)&&(p_game_info->board[1][1]==X_SYMBOL)&&(p_game_info->board[2][1]==X_SYMBOL)||
(p_game_info->board[0][2]==X_SYMBOL)&&(p_game_info->board[1][2]==X_SYMBOL)&&(p_game_info->board[2][2]==X_SYMBOL)||
(p_game_info->board[0][0]==X_SYMBOL)&&(p_game_info->board[1][1]==X_SYMBOL)&&(p_game_info->board[2][2]==X_SYMBOL)||
(p_game_info->board[0][2]==X_SYMBOL)&&(p_game_info->board[1][1]==X_SYMBOL)&&(p_game_info->board[2][0]==X_SYMBOL))
{
p_game_info->status=P1_WON;
return;
}
else
{
p_game_info->status=DRAW;
return;
}
}
game.h
#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED
#define MAX_NAME_LEN 50
enum Bool { False, True };
enum status { P1_TURN, P2_TURN, P1_WON, P2_WON, DRAW };
typedef enum Bool boolean;
static const char SPACE= '-';
static const char X_SYMBOL = 'X';
static const char O_SYMBOL = 'O';
struct game {
char board[3][3];
char playerNames[2][MAX_NAME_LEN];
int status;
boolean finished;
};
void play_game();
void initialise_game(struct game* p_game_info, char* name1, char* name2);
void draw_banner();
void display_board( char board[3][3]);
void print_status (struct game*p_game_info );
void display_board_positions ();
void process_move(struct game* p_game_info);
void finished_game(struct game* p_game_info);
#endif // game
Current output
---------------
0 | 1 | 2
3 | 4 | 5
6 | 7 | 8
GAME STATUS
enter number for 'O' from 0-8
2
- | - | O
- | - | -
- | - | -
Process returned 0 (0x0) execution time : 7.731 s
Press any key to continue.
Your question is indeed chaotic. I'm not sure what you really want to know, but notice that 'else if (p_game_info->status=P2_TURN){' is wrong. You need a double equal sign there.

Wrong answer from a program (infix notation->postfix notation) in C

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;

Comments(/*...*/) longer than one line

I am supposed to count the /*...*/ comments in a file and I was wondering if this code is right or am I missing something out?
My Code
void commentsLongerThanOneLine(FILE* inputStream, FILE* outputStream) {
int count = 0, c, state = 1;
while ((c = fgetc(inputStream) != EOF)) {
switch (state) {
case 1: switch (c) {
case '/': state = 2; break;
}
break;
case 2: switch (c) {
case '/': state = 3; break;
case '*': state = 4; break;
default: state = 1;
}
break;
case 3: switch (c) {
case '\n': state = 1; break;
default: state = 4; count++;
}
break;
case 4:switch (c) {
case'*': if (c == '\n') count++; break;
default: state = 4; if (c == '\n') count++;
}
}
}
fprintf(outputStream, "Comments longer than one line: %d\n", count);
}

Resources