Case/Switch in C not working - c

I am making a game for school this is a basic slot machine it will randomly generate numbers and converts the numbers to chars in a separate array. This seems to not be working as the statement is completely ignored. It doesn't give the right output and some time they will just go to blanks.
Output:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
/*
George Mason
Slots
Date Started: 4/25/16
Date Finished:
Dr K.
*/
void loadScreen();
void spacer();
void tabSpacer();
void clearScr();
int printMachine(char*, int);
int randomNum(int*, int);
int convertNum(int*, char*, int);
int rand_int();
void game();
int main(){
srand(time(NULL));
int stop;
loadScreen();
clearScr();
game();
scanf("%d", &stop);
}
void game(){
int tokens = 5, randomNums[9], x, y = 9;
char randomChars[9], userInput;
randomNum(randomNums, 9);
convertNum(randomNums, randomChars, 9);
printMachine(randomChars, 9);
}
int printMachine(char* randomChars, int y){
printf("-------------\n");
printf("| %c | %c | %c | \n", randomChars[0], randomChars[1], randomChars[2]);
printf("| %c | %c | %c | \n", randomChars[3], randomChars[4], randomChars[5]);
printf("| %c | %c | %c | \n", randomChars[6], randomChars[7], randomChars[8]);
printf("-------------");
}
int randomNum(int* randomNums, int y){
int x,a = 0, b = 9;
for(x = 0; x < y; x++){
randomNums[x] = ((rand() % (b-a+1)) + a);
}
}
int convertNum(int* randomNums, char* randomChars, int y){
int x;
for(x = 0; x < 9; x++){
switch(randomNums[x]){
case 1:
randomChars[x] = '#';
break;
case 2:
randomChars[x] = '#';
break;
case 3:
randomChars[x] = '$';
break;
case 4:
randomChars[x] = '+';
break;
case 5:
randomChars[x] = '&';
break;
case 6:
randomChars[x] = '*';
break;
case 7:
randomChars[x] = '?';
break;
case 8:
randomChars[x] = '!';
break;
case 9:
randomChars[x] = '~';
break;
default:
randomChars[x] = 'e';
break;
}
}
}
void loadScreen(){
int x;
for(x = 0; x < 3; x++){
spacer();
}
tabSpacer();
printf("Please wait 5 seconds while we load the saved data.\n");
tabSpacer();
printf(" If there is no saved data one will be created.");
sleep(5);
}
void spacer(){
int x;
for(x = 0; x < 3; x++){
printf("\n");
}
}
void tabSpacer(){
printf("\t ");
}
void clearScr(){
system("cls");
}

You have forgot to keep break; after every case so it will run all cases i.e from case 1 to case 9.
At the end it will save randomChars[x] = '~'; (case 9).
case 1:
randomChars[x] = '#';
break;
case 2:
randomChars[x] = '#';
break;
.
.
.
.
case 7:
randomChars[x] = '?';
break;
case 8:
randomChars[x] = '!';
break;
case 9:
randomChars[x] = '~';
break;
EDIT:
why your function return type is int when you are not returning any value. change int to void.
function game() is not declared before main()
I am getting Output like this:

Related

Can't assign elements of structure array correctly in C

I'm a beginner at C and I'm having some trouble with this.
I'm trying to mimic the behabiour of an automatic fast food order machine.
When I print the elements of the product array they are all the same.
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
char name[12];
float prize;
}PRODUCT;
typedef struct{
unsigned prodAmount;
unsigned orderNumber;
PRODUCT prod[10];
}ORDER;
void menu(ORDER*);
int main() //main
{
ORDER currentOrder = {currentOrder.prodAmount = 0};
menu(&currentOrder);
return 0;
}
void menu(ORDER*currentOder){
char option;
float total;
do{
total = 0;
for(int i = 0; i < currentOder->prodAmount; i++) total += currentOder->prod->prize;
system("clear");
printf("Welcome!\n");
printf("What would you like today?\n");
printf("1-. BURGER 3.99$\n");
printf("2-. CHIPS 0.99$\n");
printf("3-. DRINK 1.99$\n");
printf("4-. 6 NUGGETS 2.99$\n");
printf("5-. ICE CREAM 2.99$\n");
printf("6-. MENU 5.99$\n");
printf("0-. PAY\n");
printf("Products: %i\n", currentOder->prodAmount);
printf("TOTAL: %f$\n", total);
while((option = getchar()) == '\n');
switch (option){
case '1': strcpy(currentOder->prod[currentOder->prodAmount].name, "Hamburger");
currentOder->prod[currentOder->prodAmount].prize = 3.99;
break;
case '2': strcpy(currentOder->prod[currentOder->prodAmount].name, "Chips");
currentOder->prod[currentOder->prodAmount].prize = 0.99;
break;
case '3': strcpy(currentOder->prod[currentOder->prodAmount].name, "Drink");
currentOder->prod[currentOder->prodAmount].prize = 1.99;
break;
case '4': strcpy(currentOder->prod[currentOder->prodAmount].name, "Nuggets");
currentOder->prod[currentOder->prodAmount].prize = 2.99;
break;
case '5': strcpy(currentOder->prod[currentOder->prodAmount].name, "Ice cream");
currentOder->prod[currentOder->prodAmount].prize = 2.99;
break;
case '6': strcpy(currentOder->prod[currentOder->prodAmount].name, "Menu");
currentOder->prod[currentOder->prodAmount].prize = 5.99;
}
currentOder->prodAmount++;
}while(option != '0' && currentOder->prodAmount < 10);
system("clear");
printf("Your order:\n");
for(int i = 0; i < currentOder->prodAmount-1; i++) printf("%s\t%f$\n", currentOder->prod->name, currentOder->prod->prize);
printf("TOTAL: %f\n", total);
}
This is a static array of structures so I think I don't have to use malloc. I can't see what is not working. Thank you!!
When you have an array:
struct X a[10];
then all these lines do the same thing:
a[0].field = 1;
(*a).field = 1;
a->field = 1;
This is the problem with your loop printing the elements of the prod array:
for(int i = 0; i < currentOder->prodAmount-1; i++)
printf("%s\t%f$\n", currentOder->prod->name, currentOder->prod->prize);
You should use i as an index instead, because the compiler won't do that for you:
for(int i = 0; i < currentOder->prodAmount-1; i++)
printf("%s\t%f$\n", currentOder->prod[i].name, currentOder->prod[i].prize);
There is a similar mistake where you calculate the total.

Convert the array to a number starting with 0.x (C)

I have a function for translating the fractional part of the entered number into another number system (not the most beautiful code):
void FracToAny(double D, int q, int t)
{
double b[10] = {0};
for (int i = 1; i < t; i++)
{
double DP = D * q;
D = modf(DP, &b[i]);
if (D == 0)
{
break;
}
D = DP - b[i];
}
for (int i = 0; i < t; i++)
{
if (q == 16)
{
switch ((int)b[i])
{
case 10:
printf("A");
break;
case 11:
printf("B");
break;
case 12:
printf("C");
break;
case 13:
printf("D");
break;
case 14:
printf("E");
break;
case 15:
printf("F");
break;
default:
printf("%d", (int)b[i]);
break;
}
}
}
}
As a result, I get an array of double, which is a character-by-character representation of the resulting fractional part. However, I would like to return this value from the function in the form of "0.result". How can I do this?
It would be good not to use union or dynamic memory allocation (I've seen them trying to find a solution to the problem). I'd like to make it as simple as possible.
I think this is what you are trying to do (see my comment above):
Mac_3.2.57$cat etFract.c
#include <stdio.h>
#include <math.h>
int main(void)
{
int i;
double D;
int t = 3;
double b[10] = {0};
D = (3 * 16*16*16 + 4 * 16*16 + 5 *16)/(16*16*16.0);
printf("translating %f...\n", D);
for(i = 0; i < t; i++){
b[i] = modf(D, &D);
if(D == 0){
break;
}
D = b[i] * 16;
}
printf("0.");
for(int i = 0; i < t; i++){
switch((int)b[i]*16){
case 10:
printf("A\n");
break;
case 11:
printf("B\n");
break;
case 12:
printf("C\n");
break;
case 13:
printf("D\n");
break;
case 14:
printf("E\n");
break;
case 15:
printf("F\n");
break;
default:
printf("%d", (int)(b[i]*16));
break;
}
}
printf("\n");
return(0);
}
Mac_3.2.57$cc etFract.c
Mac_3.2.57$./a.out
translating 3.269531...
0.450
Mac_3.2.57$

Turn character into number and arrange the number in c

int T, i;
scanf("%d", &T);
char a[T], b[T], c[T];
int temp[T], temp2[T], temp3[T];
int point1[T], point2[T], point3[T];
for(i=0;i<T; i++){
scanf("%c %c %c", &a[i], &b[i], &c[i]);
switch(a[i]){
case '!':
point1[i] = 5;
break;
case '%':
point1[i] = 4;
break;
case '&':
point1[i] = 3;
break;
case '^':
point1[i] = 2;
break;
case '|':
point1[i] = 1;
break;
default :
point1[i]=10;
}
switch(b[i]){
case '!':
point2[i] = 5;
break;
case '%':
point2[i] = 4;
break;
case '&':
point2[i] = 3;
break;
case '^':
point2[i] =2;
break;
case '|':
point2[i] =1;
break;
default :
point2[i]=10;
}
switch(c[i]){
case '!':
point3[i] = 5;
break;
case '%':
point3[i] = 4;
break;
case '&':
point3[i] = 3;
break;
case '^':
point3[i] =2;
break;
case '|':
point3[i] =1;
break;
default :
point3[i]=10;
}
if(point1[i]<point2[i]) {
temp[i]=point1[i];
point1[i]=point2[i];
point2[i]=temp[i];
}
if(point1[i]<point3[i]){
temp2[i]=point1[i];
point1[i]=point3[i];
point3[i]=temp2[i];
}
if(point2[i]<point3[i]){
temp3[i]=point2[i];
point2[i]=point3[i];
point3[i]=temp3[i];
}
printf("%d %d %d\n", point1[i], point2[i], point3[i]);
}
return 0;
So first of all, i was asked to input certain characters randomly arranged and make them printed arranged from the highest precedence.
The precedence of the operators (from the highest to the lowest) are "!" (logical NOT), "%" (remainder), "&"
(bitwise AND), "^" (bitwise XOR), , "|" (bitwise OR).
So i try to change the characters into numbers and try to arrange the number first then change the number again to the characters.
But when i try to check if the numbers have been correctly arranged, it's not.
Any idea what's wrong with my code?
Or any idea to make my code simpler without having to turn the characters into numbers?
Here's the sample
Sample Input
3
& ^ %
& ^ !
& ^ !
Sampe Output
Case #1: % & ^
Case #2: ! & ^
Case #3: ! & ^
A few issues have already been noted in the comments. Specifically, scanf leaves the trailing newline in the input buffer. You can fix that using the suggestion by #4386427.
You can avoid manually assigning numbers for each character by noting that their ASCII is already in required order. That is, '!' < '%' < '&' < '^' < '|'. So you can simply read them into a char array of the appropriate size and just sort them in ascending order before printing the char array. This will significantly shorten and clean up your code.
#include <stdio.h>
#include <stdlib.h>
int cmpfunc (const void * a, const void * b) {
return (*((char*)a) > *((char*)b)) - (*((char*)a) < *((char*)b));
}
int main(int argc, char *argv[])
{
int T, i, j;
scanf(" %d", &T);
/* TODO: Check if number of chars per line is T or 3. */
char *a = malloc(T * sizeof(char));
for(i = 0; i < T; i++) {
for (j = 0; j < T; j++) {
scanf(" %c", &a[j]);
}
printf("Before sort\n");
for (j = 0; j < T; j++) {
printf("%c ", a[j]);
}
printf("\n");
qsort(a, T, sizeof(a[0]), cmpfunc);
printf("After sort\n");
for (j = 0; j < T; j++) {
printf("%c ", a[j]);
}
printf("\n");
}
free(a);
return 0;
}

Segmentation Fault Error (C)

I am currently writing a program that is supposed to receive input from a text file and output statistics about the text such as the number of letters, size of words and how often they occur, and how many times each word occurs. However, every time I run the program, I get a segmentation fault error. The program runs until I hit the line Letter Count Analysis. The I receive the segmentation fault error. Here is some sample text:
1
Hello my name is Bob
I live in Canada
The number represents how many lines are supposed to be read. What should I do to correct my issue? I am very new to programming so I'm sure it is something basic.
#include <stdio.h>
#include <string.h>
#define MAX_LINE_LENGTH 80
#define MAX_WORD_LENGTH 20
#define MAX_LINES 10
void letterAnalysis(char [][MAX_LINE_LENGTH], int lineTotal);
int wordLengthAnalysis(char [][MAX_LINE_LENGTH], int lineTotal, int wordLength);
void wordAnalysis(char [][MAX_LINE_LENGTH], int lineTotal);
int main (void){
int lineTotal, wordSize;
char text[lineTotal][MAX_LINE_LENGTH];
char n[1];
fgets(n, 10, stdin);
lineTotal = n[0] - '0';
for(int i = 0; i < lineTotal; i++){
fgets(text[i], MAX_WORD_LENGTH, stdin);
}
printf("\n***Letter count analysis***\n");
letterAnalysis(text, lineTotal);
printf("\n***Word length analysis***\n");
for (int i = 1; i <= MAX_WORD_LENGTH; i++){
wordSize = wordLengthAnalysis(text, lineTotal, i);
if (wordSize == 1){
printf("\n%-2d\tword of length %d", wordSize, i);
}
else{
printf("\n%-2d\twords of length %d", wordSize, i);
}
}
printf("\n\n***Word analysis***\n");
wordAnalysis(text, lineTotal);
return 0;
}
void letterAnalysis(char text[][MAX_LINE_LENGTH], int lineTotal){
int alphabet[26] = {0};
for (int i = 0; i < lineTotal; i++){
for(int j = 0; j < MAX_LINE_LENGTH; j++){
switch(text[i][j]){
case 'A': case 'a':
alphabet[0]++;
break;
case 'B': case 'b':
alphabet[1]++;
break;
case 'C': case 'c':
break;
alphabet[2]++;
case 'D': case 'd':
alphabet[3]++;
break;
case 'E': case 'e':
alphabet[4]++;
break;
case 'F': case 'f':
alphabet[5]++;
break;
case 'G': case 'g':
alphabet[6]++;
break;
case 'H': case 'h':
alphabet[7]++;
break;
case 'I': case 'i':
alphabet[8]++;
break;
case 'J': case 'j':
alphabet[9]++;
break;
case 'K': case 'k':
alphabet[10]++;
break;
case 'L': case 'l':
alphabet[11]++;
break;
case 'M': case 'm':
alphabet[12]++;
break;
case 'N': case 'n':
alphabet[13]++;
break;
case 'O': case 'o':
alphabet[14]++;
break;
case 'P': case 'p':
alphabet[15]++;
break;
case 'Q': case 'q':
alphabet[16]++;
break;
case 'R': case 'r':
alphabet[17]++;
break;
case 'S': case 's':
alphabet[18]++;
break;
case 'T': case 't':
alphabet[19]++;
break;
case 'U': case 'u':
alphabet[20]++;
break;
case 'V': case 'v':
alphabet[21]++;
break;
case 'W': case 'w':
alphabet[22]++;
break;
case 'X': case 'x':
alphabet[23]++;
break;
case 'Y': case 'y':
alphabet[24]++;
break;
case 'Z': case 'z':
alphabet[25]++;
break;
}
}
}
for(int i = 0; i <= 25; i++){
printf("%c: \t%d\n",'a' + i, alphabet[i]);;
}
}
int wordLengthAnalysis(char text[][MAX_LINE_LENGTH], int lineTotal, int wordLength){
int sentenceLength;
int counter, wordSize = 0;
for(int i = 0; i < lineTotal; i++){
sentenceLength = strlen(&text[i][0]);
for(int j = 0; j < sentenceLength + 2; j++){
if(text[i][j] == ' '){
if(counter == wordLength){
++wordSize;
counter = 0;
}
else{
counter = 0;
}
}
else{
counter++;
}
}
}
return wordSize;
}
void wordAnalysis(char text[][MAX_LINE_LENGTH], int lineTotal){
char maxWords[800];
char word[MAX_LINE_LENGTH], word2[MAX_WORD_LENGTH], *ptrText, *ptrTextCounter;
int counter, textCounter = 0;
int sentenceLength, wordTracker;
int lineFlag;
for(int i = 0; i < lineTotal; i++){
ptrText = &text[i][0];
sentenceLength = strlen(ptrText);
counter = 0;
for (int j = 0; j < sentenceLength + 1; j++){
wordTracker = 1;
if (text[i][j] == ' ' ){
if (counter != 0){
sprintf(word, "%.*s", counter, ptrText);
ptrTextCounter = &text[i][j+1];
lineFlag = j;
if(strstr(maxWords, word) == NULL){
for (int k = i; k < lineTotal; k++){
textCounter = 0;
if (lineFlag == j){
ptrTextCounter = &text[i][j+1];
}
else{
lineFlag = 0;
ptrTextCounter = &text[i][j+1];
}
for ( ; lineFlag < sentenceLength; lineFlag++){
if(text[k][lineFlag] == ' '){
if (textCounter != 0){
if(textCounter == counter){
sprintf(word2, "%.*s", textCounter, ptrTextCounter);
if(strcmp(word, word2) == 0){
wordTracker++;
}
}
ptrTextCounter = &text[k][lineFlag];
textCounter = 0;
}
else{
ptrTextCounter = &text[k][lineFlag+1];
}
}
else{
textCounter++;
}
}
}
if(wordTracker == 1){
printf("\n\"%.*s\"\t\tappeared %d time", counter, ptrText, wordTracker);
}
else{
printf("\n\"%.*s\"\t\tappeared %d time", counter, ptrText, wordTracker);
}
}
strcat(maxWords, word);
ptrText = &text[i][j+1];
counter = 0;
}
else{
ptrText = &text[i][j+1];
}
}
else{
counter++;
}
}
}
}
I get a couple of warnings:
main.c:17:14: warning: variable length array used [-Wvla]
char text[lineTotal][MAX_LINE_LENGTH];
^
main.c:17:15: warning: variable 'lineTotal' is uninitialized when used here [-Wuninitialized]
char text[lineTotal][MAX_LINE_LENGTH];
^~~~~~~~~
You haven't initialized lineTotal but are using it. This causes undefined behavior.
main.c:64:21: warning: code will never be executed [-Wunreachable-code]
alphabet[2]++;
^~~~~~~~
Your break; is likely misplaced.
main.c:152:20: warning: variable 'counter' may be uninitialized when used here [-Wconditional-uninitialized]
if(counter == wordLength){
^~~~~~~
Again, you're using a potentially uninitialized variable.
Also:
char n[1];
fgets(n, 10, stdin);
Your array has one element but you tell fgets it can access up to n[10].
Hint (if it wasn't obvious already): never program C without warnings.

C pointers in reversi games

I want to that this function after than player 1 puts position program chack where on the left is player's 1 pawn and all of opponent's paws between player's 1 two pawns turning on 'X', like in reversi games.
This is whole unfinished code:
#include<stdio.h>
#define SIZE 7
char board[SIZE][SIZE];
char letter;
int number;
void make_board(char tab[SIZE][SIZE]){
int w,k;
for(w=0; w < SIZE; w++){
for(k=0; k < SIZE; k++){
tab[w][k] = '.';
}
}
tab[0][0] = 'X';
tab[1][0] = '1';
tab[2][0] = '2';
tab[3][0] = '3';
tab[4][0] = '4';
tab[5][0] = '5';
tab[6][0] = '6';
tab[0][1] = 'A';
tab[0][2] = 'B';
tab[0][3] = 'C';
tab[0][4] = 'D';
tab[0][5] = 'E';
tab[0][6] = 'F';
tab[4][4] = 'X';
tab[4][3] = 'O';
tab[3][4] = 'O';
tab[3][3] = 'X';
}
char draw_board(char tab[SIZE][SIZE]){
int w, k;
for(w=0; w < SIZE; w++){
for(k=0; k < SIZE; k++){
printf("%2c", tab[w][k]);
}
printf("\n");
}
}
int translate(char letter){
int letter_to_number;
switch(letter){
case 'A':
case 'a':
letter_to_number = 1;
break;
case 'B':
case 'b':
letter_to_number = 2;
break;
case 'C':
case 'c':
letter_to_number = 3;
break;
case 'D':
case 'd':
letter_to_number = 4;
break;
case 'E':
case 'e':
letter_to_number = 5;
break;
}
return letter_to_number;
}
int finished(char tab[SIZE][SIZE]){ // looking '.' in array
int i,j;
for(i=1;i<=SIZE;i++){
for(j=1;j<=SIZE;j++){
if(tab[i][j]=='.'){
return 1;
}else{
return 0; // if don't find any '.' game is finish
}
}
}
}
void hit(char tab[SIZE][SIZE], int player ){
int i,j;
int *poz1, *poz2;
printf("Call out a letter and a number of a row and column on the grid:\n");
scanf(" %c %d", &letter, &number);
i=translate(letter);
poz1=&tab[number][i];
if(tab[number][i]=='.'){
if(player==1){
*poz1='X';
for(poz1-1;*poz1=='X';poz1--){
poz2=&poz1;}
poz1=&tab[number][i];
for(poz2;poz2<=poz1;poz2++){
*poz2='X';}
}else{
*poz1='O';
for(poz1-1;*poz1=='O';poz1--){
poz2=&poz1;}
poz1=&tab[number][i];
for(poz2;poz2<=poz1;poz2++){
poz2='O';}
}
}else{
printf("On this place already is pawn\n");
}
draw_board(board);
getchar();
}
int main(){
int i,j,k, pg1=0, pg2=0, player=1;
make_board(board);
draw_board(board);
do{
if(player==1){
printf("Player 1\n");
hit(board, gracz);
k=finished(board);
gracz=2;
}else{
printf("Player 2\n");
hit(board, gracz);
k=finished(board);
player=1;
}
}while(k==1);
for(i=1;i<=SIZE;i++){
for(j=1;j<=SIZE;j++){
if(board[i][j]=='X'){
pg1++;
}else{
pg2++;
}
}
}
if(pg1>pg2){
printf("Player 1 wins");
}else{
printf("Player 2 wins");
}
return 0;
}
Bit buggy code:
poz1=&tab[number][i];
if(tab[number][i]=='.'){
if(player==1){
*poz1='X';
for(poz1-1;*poz1=='X';poz1--){
poz2=&poz1;}
poz1=&tab[number][i];
for(poz2;poz2<=poz1;poz2++){
*poz2='X';}
How can you asgn &pos1 to pos2. For this you need pointer to a pointer, i.e, pos 2 should be declared as **pos2.
Also, what do you want to achieve by looping over poz1 (set 'X' earlier)?
Anyhow, some cleanup to your code:
if(tab[number][i]=='.'){
if(player==1){ //considering player 1 is 'X'
// Loop to the left till you find opponent's piece or come to edge.
for(j=i-1;tab[number][j]=='O' && j!=0 ;j--)
;
// Validation check
if(i-j <=1 || tab[number][j] != 'X');
//Invalid move
return 1;
else
// convert all the opponents pieces between two of yours piece
for(k=i;k>j;k--)
tab[number][k] = 'X';
The above part of code is informative only..this will check if the move is valid for left side..and if valid convert the opponents pieces.. you need to understand this and put similar logic for "Right", "Diagonal" etc to complete the reversi game.

Resources