C switch returns default inside if/else - c

I have the following problem: i have two switch statements. They work perfectly when separated, but the minute I put both of them into an if/else. switch always returns the default(error). I am sorry for the difficult wording, now I have copied in the whole program so you can check it, I have tried what you said, but it didn't seem to help. So for an example, when it asks for the number, my input is 2. Then it asks for what character do I want to choose (+,-,/,*), and no matter which I write in, it gives me the default output like I have type a wrong character.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
void tomb_beolvas(int *szamok);
void tomb_kiir(int *szamok);
void tomb_sorrend(int *szamok);
void sorrend_kiir(int *szamok);
void kalkulator(int *szamok);
int main() {
int szamok[10];
tomb_beolvas(szamok);
tomb_kiir(szamok);
tomb_sorrend(szamok);
sorrend_kiir(szamok);
kalkulator(szamok);
return 0;
}
void tomb_beolvas(int *szamok) {
int i;
srand(time(0));
for (i = 0; i < 10; i++) {
szamok[i] = rand() % (10) + 1;
}
return;
}
void tomb_kiir(int *szamok) {
int i;
for (i = 0; i < 10; i++) {
printf("%d\n", szamok[i]);
}
return;
}
void tomb_sorrend(int *szamok) {
int i;
int a, j;
for (i = 0; i < 10; ++i) {
for (j = i + 1; j < 10; j++) {
if (szamok[i] > szamok[j]) {
a = szamok[i];
szamok[i] = szamok[j];
szamok[j] = a;
}
}
}
return;
}
void sorrend_kiir(int *szamok) {
int i;
for (i = 0; i < 10; i++) {
printf("\n%d", szamok[i]);
}
return;
}
void kalkulator(int *szamok) {
char jel;
int a, b, donto;
printf("\nKerem valassza ki milyen modon szeretne megadni az adatokat:\n"
" 1.: egyben(peldaul 5. + 8.)\n"
" 2.: kulon(peldaul + aztan 5. es 8.)\n");
scanf("%d", &donto);
if (donto == 1) {
printf("\nKerem irja be hanyadik szamokat szeretne es koze hogy milyen kalkulaciot szeretne vegezni(pl.: 5 + 8):\n");
while (scanf("%d %c %d", &a, &jel, &b)) {
switch (jel) {
case '+':
printf("%d", szamok[a-1] + szamok[b-1]);
break;
case '-':
printf("%d", szamok[a-1] - szamok[b-1]);
break;
case '*':
printf("%d", szamok[a-1] * szamok[b-1]);
break;
case '/':
printf("%d", szamok[a-1] / szamok[b-1]);
break;
}
}
} else
if (donto == 2) {
printf("Adj meg egy jelet (+, -, *, /): ");
scanf("%c", &jel);
printf("add meg hanyadik szamokkal akarsz szamolni: ");
scanf("%d %d", &a, &b);
switch (jel) {
case '+':
printf("%d + %d = %d", szamok[a], szamok[b], szamok[a] + szamok[b]);
break;
case '-':
printf("%d - %d = %d", szamok[a], szamok[b], szamok[a] - szamok[b]);
break;
case '*':
printf("%d * %d = %d", szamok[a], szamok[b], szamok[a] * szamok[b]);
break;
case '/':
printf("%d / %d = %d", szamok[a], szamok[b], szamok[a] / szamok[b]);
break;
// operator doesn't match any case constant +, -, *, /
default:
printf("Error! operator is not correct");
}
}
return;
}

There is nothing wrong with your switch statements, however:
int szamok[]={};
You can't make an empty array, you should declare it with a size:
const int size = 10;
int szamok[10];
From what I can tell, you invoked undefined behavior by accessing szamok with an out of bounds index (which is any positive number, as you got an empty array).

I'm afraid your problem is a classic scanf() issue: instead of scanf("%c", &jel); you should use
scanf(" %c", &jel); // notice the initial space before the `%c`
This skips the newline left pending after the scanf("%d", &donto);.

Related

I don't understand this crash

This is my code for solving the problem "Students Marks Sum" in Hackerrank:
(Link: https://www.hackerrank.com/challenges/students-marks-sum/problem?)
#include <string.h>
#include <math.h>
#include <stdlib.h>
//Complete the following function.
int marks_summation(int* marks, int number_of_students, char gender) {
int result = 0;
switch (gender){
case 'b':
while(marks != NULL){
result += (*marks);
marks += 2;
}
case 'g':
++marks;
while(marks != NULL){
result += (*marks);
marks += 2;
}
break;
}
return result;
}
int main() {
int number_of_students;
char gender;
int sum;
scanf("%d", &number_of_students);
int *marks = (int *) malloc(number_of_students * sizeof (int));
for (int student = 0; student < number_of_students; student++) {
scanf("%d", (marks + student));
}
scanf(" %c", &gender);
sum = marks_summation(marks, number_of_students, gender);
printf("%d", sum);
free(marks);
return 0;
}
When I move this code into an IDE (in my situation, it's DEV C/C++), it was crashed when my debug ran into my function marks_summation.
Error in line:
result += (*marks);
The problem is in your assumption that if you move out of the range of dynamically allocated memory the pointer value will change to NULL:
while(marks != NULL){
result += (*marks);
marks += 2;
}
There are a number of approaches you can pick to iterate over such array.
You can calculate the memory address that will no longer be valid to read and check at each iteration if your pointer is smaller than it:
int marks_summation(int* marks, int number_of_students, char gender) {
int result = 0;
int* marksEnd = marks + number_of_students;
switch (gender){
case 'b':
while(marks < marksEnd){
result += (*marks);
marks += 2;
}
case 'g':
++marks;
while(marks < marksEnd){
result += (*marks);
marks += 2;
}
break;
}
return result;
}

How can I call my array in one function to another function and display specific data from that array?

#include <stdio.h>
int main(void) {
int choice;
do {
choice = getUserChoice();
switch (choice) {
case 1:
gameResults();
break;
case 2:
printf("game results:\n ");
break;
case 3:
printf("selected choice is 3\n");
break;
case 4:
printf("selected choice is 4\n");
break;
case 5:
//this case is to keep the default from triggering when selecting 5.
break;
default:
printf("please select a valid number 1-5.\n");
system("pause");
}
} while (choice != 5);
}
int getUserChoice() {
int x = 0;
printf("[1]Enter game results.\n");
printf("[2]Current record (number of wins, losse, and ties)\n");
printf("[3]Display ALL results from all games won.\n");
printf("[4]Display ALL results ordered from low to high.\n");
printf("[5]Quit.\n");
scanf_s("%d", &x);
return x;
}//end getUserChoice
int gameResults() {
int gameInput[1][2];
//counter variables for loop.
int i, j;
for (i = 0; i < 1; i++) {
for (j = 0; j < 2; j++) {
printf("please enter a value for gameInput[%d][%d]: ", i, j);
scanf_s("%d", &gameInput[i][j]);
return gameInput[i][j];
}
}
}
void prinGameResults() {
gameResults();
int wins, ties, losses = 0;
if()
}
So essentially I'm working on this assignment that is asking me to create a 2D array, have the user select stuff from a menu, put in 2 values for 2 team scores (one being "your" team and the other one being the opponents) I've created the array and now I'm looking to display this array when the user calls the 2nd switch case, and display numbers of wins, ties, etc etc.. the only problem is I have no idea how to call this array into one function from another, perhaps I'm doing this the in a wrong way, is there some easier way of going about this array?
You'll want to define your array inside main so that it can be passed as an argument (alongside its dimensions) to each function.
#include <stdio.h>
#include <stdlib.h>
int getUserChoice(void);
void getGameResults(size_t n, size_t m, int res[n][m]);
void printGameResults(size_t n, size_t m, int res[n][m]);
#define ROWS 1
#define COLS 2
int main(void) {
int results[ROWS][COLS] = { 0 };
int choice;
while ((choice = getUserChoice()) != 5)
switch (choice) {
case 1:
getGameResults(ROWS, COLS, results);
break;
case 2:
printGameResults(ROWS, COLS, results);
break;
case 3:
puts("Selected (3)");
break;
case 4:
puts("Selected (4)");
break;
default:
puts("Select a valid option (1-5)");
break;
}
}
int getUserChoice(void) {
int x = 0;
puts("[1]Input results.");
puts("[2]Display results.");
puts("[3]--");
puts("[4]--");
puts("[5]Quit.");
if (scanf("%d", &x) != 1) {
fprintf(stderr, "Failed to read choice.\n");
exit(EXIT_FAILURE);
}
return x;
}
void getGameResults(size_t n, size_t m, int res[n][m]) {
for (size_t i = 0; i < n; i++) {
for (size_t j = 0; j < m; j++) {
printf("Enter a value for [%zu][%zu]: ", i, j);
if (scanf("%d", &res[i][j]) != 1) {
fprintf(stderr, "Failed to read result.\n");
exit(EXIT_FAILURE);
}
}
}
}
void printGameResults(size_t n, size_t m, int res[n][m]) {
for (size_t i = 0; i < n; i++) {
for (size_t j = 0; j < m; j++) {
printf("Value for [%zu][%zu]: %d\n", i, j, res[i][j]);
}
}
}
And for compilers that don't support variable-length arrays, you must be more rigid in your approach. There are a few ways to do this, here is one example:
#include <stdio.h>
#include <stdlib.h>
#define ROWS 1
#define COLS 2
int getUserChoice(void);
void getGameResults(int res[ROWS][COLS]);
void printGameResults(int res[ROWS][COLS]);
int main(void) {
int results[ROWS][COLS] = { 0 };
int choice;
while ((choice = getUserChoice()) != 5)
switch (choice) {
case 1:
getGameResults(results);
break;
case 2:
printGameResults(results);
break;
case 3:
puts("Selected (3)");
break;
case 4:
puts("Selected (4)");
break;
default:
puts("Select a valid option (1-5)");
break;
}
}
int getUserChoice(void) {
int x = 0;
puts("[1]Input results.");
puts("[2]Display results.");
puts("[3]--");
puts("[4]--");
puts("[5]Quit.");
if (scanf("%d", &x) != 1) {
fprintf(stderr, "Failed to read choice.\n");
exit(EXIT_FAILURE);
}
return x;
}
void getGameResults(int res[ROWS][COLS]) {
for (size_t i = 0; i < ROWS; i++) {
for (size_t j = 0; j < COLS; j++) {
printf("Enter a value for [%zu][%zu]: ", i, j);
if (scanf("%d", &res[i][j]) != 1) {
fprintf(stderr, "Failed to read result.\n");
exit(EXIT_FAILURE);
}
}
}
}
void printGameResults(int res[ROWS][COLS]) {
for (size_t i = 0; i < ROWS; i++) {
for (size_t j = 0; j < COLS; j++) {
printf("Value for [%zu][%zu]: %d\n", i, j, res[i][j]);
}
}
}

How to output elements inside of stack during RPN Calculating

I implemented an RPN Calculator in C. Now I want to output the current iteration meaning
Iteration 1: Contents: [5, 5]
Iteration 2: Contents: [25]
I am not quite sure how i am going to print them. I tried Printing them in the main function, but the output was coming
Iteration 1: Contents: 5
Iteration 2: Contents: 5
10
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_SIZE 100
int stack[MAX_SIZE];
int top = 0;
void makeEmpty()
{
top = 0;
}
bool isEmpty()
{
return top == 0;
}
bool isFull()
{
return top == MAX_SIZE;
}
void push(int value)
{
stack[top++] = value;
}
int pop()
{
if(isEmpty())
{
printf("Not enough operands in expression\n");
exit(EXIT_FAILURE);
}
return stack[--top];
}
//adds 2 integers
int add(int a, int b)
{
return a + b;
}
//subtracts 2 integers
int sub(int a, int b)
{
return a - b;
}
//multiplies 2 integers
int mul(int a, int b)
{
return a * b;
}
//divides 2 integers
int divide(int a, int b)
{
return a / b;
}
int main(void)
{
char ch;
while(1)
{
//Emptying the stack before the user enters another expression
makeEmpty();
printf("Enter an RPN expression: ");
//Reads expression from user
scanf("%c", &ch);
//parse all characters until a newline is reached
while(1)
{
if(ch == '\n')
break;
//if character is an integer
if(ch >= 48 && ch <= 57)
{
if(!isFull())
{
//convert char to int and push integer onto stack
printf("Iteration %d: Contents: %d \n", (top+1), (ch-48));
push(ch - 48);
}
else
{
//stack ran out of space, print error and exit program
printf("Expression is too complex\n");
exit(EXIT_FAILURE);
}
}
switch(ch)
{
case '+':
push(add(pop(), pop()));
break;
case '-':
push(sub(pop(), pop()));
break;
case '*':
push(mul(pop(), pop()));
break;
case '/':
push(divide(pop(), pop()));
break;
case '=':
printf("%d\n", pop());
break;
}
//get next character
scanf("%c", &ch);
}
}
return 0;
}
You can easily workaround it in your program without creating temporary stacks:
void print_stack(void)
{
printf("[");
for(int index = top -1; index >= 0; index--)
{
printf("%d%s", stack[index], index ? ", " : "");
}
printf("]\n");
}

Random Math Problem Generator: userAnswer and realAnswer keep returning 0

This is a random math problem generator program.
The problem is my input answer and the real answer keeps returning 0.
What's the problem here? I can't find out why.
Here's the code step by step...
import libraries
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
calling functions
int getRandNum(int i, int lower, int upper, int randNum);
int getRandOp(int i, int opSel, char randOp);
int getRealAnswer(char randOp, int randNum1, int randNum2, int realAnswer);
void showQuestion(int i, int randNum1, int randOp, int randNum2, int realAnswer, int
userAnswer);
int getUserAnswer(int userAnswer);
void answerCompare(int realAnswer, int userAnswer);
main() function
int main(void) // main fucntion
{
int i;
int randNum1, randNum2;
int userAnswer, realAnswer;
char randOp;
srand(time(NULL));
for (i = 1; i <= 5; i++)
{
showQuestion(i, randNum1, randOp, randNum2, realAnswer, userAnswer);
getUserAnswer(userAnswer);
getRealAnswer(randNum1, randNum2, randOp, realAnswer);
answerCompare(realAnswer, userAnswer);
printf("Real Answer = %d User Answer = %d\n\n", realAnswer, userAnswer);
}
return 0;
}
getRandNum() function
int getRandNum(int i, int lower, int upper, int randNum) // get random number within range using rand() function
{
lower = (20 * (i - 1)) + 1;
upper = 20 * I;
randNum = (rand() % (upper - lower + 1)) + lower;
return randNum;
}
getRandOp() function
int getRandOp(int i, int opSel, char randOp) // get random operator within list using rand() function
{
char opList[4] = {'+', '-', '*', '/'};
opSel = rand() % 4;
randOp = opList[opSel];
return randOp;
}
getRealAnser() function
int getRealAnswer(char randOp, int randNum1, int randNum2, int realAnswer) // get real answer of the problem (problematic part: always returns 0)
{
switch (randOp)
{
case '+':
realAnswer = randNum1 + randNum2;
case '-':
realAnswer = randNum1 - randNum2;
case '*':
realAnswer = randNum1 * randNum2;
case '/':
realAnswer = randNum1 / randNum2;
default:
break;
}
return realAnswer;
}
showQuestion() function
void showQuestion(int i, int randNum1, int randOp, int randNum2, int realAnswer, int userAnswer) // print out math question
{
int randNum, opSel, lower, upper;
printf("##### Question Number %d #####\n", I);
randNum1 = getRandNum(i, lower, upper, randNum);
randOp = getRandOp(i, opSel, randOp);
randNum2 = getRandNum(i, lower, upper, randNum);
realAnswer = getRealAnswer(randNum1, randNum2, randOp, realAnswer);
printf("%d %c %d = ", randNum1, randOp, randNum2);
}
getUserAnswer() function
int getUserAnswer(int userAnswer) // user input answer of the problem (problematic part: always returns 0)
{
userAnswer = scanf("%d", &userAnswer);
return userAnswer;
}
answerCompare() function
void answerCompare(int realAnswer, int userAnswer) // compare user answer and real answer of the problem and print result
{
if (userAnswer == realAnswer)
{
printf("You are correct!\n");
}
else if (userAnswer != realAnswer)
{
printf("You are wrong!\n");
}
else
{
printf("Error! Invalid Comparison!\n");
}
}
Change getUserAnswer to something like this:
int getUserAnswer()
{
int userAnswer = -1;
userAnswer = scanf("%d", &userAnswer);
return userAnswer;
}
And use it like this:
userAnswer = getUserAnswer();
Do something similar for real answer code.
Also the answerCompare can be simplified to an "if-else" structure since if the == fails by definition they are !=. (It would never reach the 'invalid comparison' code.)
Also in getRealAnswer you'll need breaks for each case or simply return in each case. As posted each operator falls through to next case.
You have to give, both of your functions, a pointer of int if you want to modify the value of a variable you have on main. So for example for the first function:
void getUserAnswer(int* userAnswer) // user input answer of the problem (problematic part: always returns 0)
{
*userAnswer = -1;
scanf("%d", &(*userAnswer)); // you don't need to store return value of scanf
}
int main (void) {
/* do stuff */
int userAnswer;
getUserAnswer(&userAnswer); // use func like this
/* do stuff */
return 0;
}
void getRealAnswer(char randOp, int randNum1, int randNum2, int* realAnswer) // get real answer of the problem (problematic part: always returns 0)
{
switch (randOp)
{
case '+': {
*realAnswer = randNum1 + randNum2;
} break;
case '-': {
*realAnswer = randNum1 - randNum2;
} break;
case '*': {
*realAnswer = randNum1 * randNum2;
} break;
case '/': {
*realAnswer = randNum1 / randNum2;
} break;
default:
break;
}
}
Passing a pointer to the variable you want to modify you don't need to return any value from your function, so I changed it to void

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;
}

Resources