optimization Tic Tac Toe Game in C - c

I'm beginner learner in C and one of the assignments I got was to write a Tic Tac Toe game. I have the game running but every time you place X on O position or vice versa it overwrites it. I would also appreciate comments on optimizing the code, because I'm a beginner and don't know a lot of concepts. Thank you! this is what I've got so far
#include<stdio.h>
void redrawBoard(char array[]);
void markBoard (int x, int o, char array[]);
int checkForWin(char array[]);
int checkForWin(char array[])
{
int a;
char x = 'X';
char o = 'O';
if (array[0] == x && array[4] == x && array[8] == x) // winning cases for x
return 1;
if (array[2] == x && array[4] == x && array[6] == x)
return 1;
if (array[0] == x && array[1] == x && array[2] == x)
return 1;
if (array[3] == x && array[4] == x && array[5] == x)
return 1;
if (array[6] == x && array[7] == x && array[8] == x)
return 1;
if (array[0] == x && array[3] == x && array[6] == x)
return 1;
if (array[1] == x && array[4] == x && array[7] == x)
return 1;
if (array[2] == x && array[5] == x && array[8] == x)
return 1;
if (array[1] == x && array[4] == x && array[6] == x && array[8] ==x) //checking for draw with x combinations 1st pattern
return 3;
if (array[0] == x && array[2] == x && array[4] == x && array[7] ==x)
return 3;
if (array[0] == x && array[4] == x && array[5] == x && array[6] ==x)
return 3;
if (array[2] == x && array[3] == x && array[4] == x && array[8] ==x)
return 3;
if (array[1] == x && array[4] == x && array[5] == x && array[6] ==x) //checking for draw with x combinations 2nd pattern
return 3;
if (array[0] == x && array[4] == x && array[5] == x && array[7] ==x)
return 3;
if (array[2] == x && array[3] == x && array[4] == x && array[7] ==x)
return 3;
if (array[1] == x && array[3] == x && array[4] == x && array[8] ==x)
return 3;
if (array[0] == o && array[4] == o && array[8] == o) //// winning cases for o
return 2;
if (array[2] == o && array[4] == o && array[6] == o)
return 2;
if (array[0] == o && array[1] == o && array[2] == o)
return 2;
if (array[3] == o && array[4] == o && array[5] == o)
return 2;
if (array[6] == o && array[7] == o && array[8] == o)
return 2;
if (array[0] == o && array[3] == o && array[6] == o)
return 2;
if (array[1] == o && array[4] == o && array[7] == o)
return 2;
if (array[2] == o && array[5] == o && array[8] == o)
return 2;
if (array[1] == o && array[4] == o && array[6] == o && array[8] == o) //checking for draw with o combinations 1st pattern
return 3;
if (array[0] == o && array[2] == o && array[4] == o && array[7] == o)
return 3;
if (array[0] == o && array[4] == o && array[5] == o && array[6] == o)
return 3;
if (array[2] == o && array[3] == o && array[4] == o && array[8] == o)
return 3;
if (array[1] == o && array[4] == o && array[5] == o && array[6] == o) //checking for draw with o combinations 2nd pattern
return 3;
if (array[0] == o && array[4] == o && array[5] == o && array[7] == o)
return 3;
if (array[2] == o && array[3] == o && array[4] == o && array[7] == o)
return 3;
if (array[1] == o && array[3] == o && array[4] == o && array[8] == o)
return 3;
else
return 0;
return(a);
}
void markBoard (int x, int o, char array[])
{
int i = 0;
char j = 'X';
char k = 'O';
while( x >= 1 && x <= 9)
{
array[x - 1] = j;
redrawBoard(array);
break;
}
while (o >= 1 && o <= 9)
{
array[o - 1] = k;
redrawBoard(array);
break;
}
}
void redrawBoard(char array[])
{
printf(" Player 1 is X; Player 2 is O;\n\n");
printf(" | | \n");
printf(" %c | %c | %c \n",array[0],array[1],array[2]);
printf(" ______|______|______ \n");
printf(" | | \n");
printf(" %c | %c | %c \n",array[3],array[4],array[5]);
printf(" ______|______|______ \n");
printf(" | | \n");
printf(" %c | %c | %c \n",array[6],array[7],array[8]);
printf(" | | \n");
}
int main()
{
int x;
int o;
char array[9] = {'1', '2','3','4','5','6','7','8','9'};
printf("tic tac toe game\n");
redrawBoard(array);
while (checkForWin(array) == 0)
{
printf("P1 start \n");
scanf("%d",&x);
markBoard(x,o,array);
printf("P2 go on\n");
scanf("%d", &o);
markBoard(x,o,array);
}
if (checkForWin(array) == 1)
printf("P1 won\n");
if (checkForWin(array) == 2)
printf("P2 won\n");
if (checkForWin(array) == 3)
printf("draw \n");
return 0;
}

The problem you mentioned is that you do not have a test when you already have a value in this cell.
About optimization:
Avoid a lot of if cases! Think about better check for checking who is winner.
For example, look at this check:
char winnerIs(char** Board, int i, int j) {
if (Board[i][j] == Board[i][(j+1)%3]
&& Board[i][j] == Board[i][(j+2)%3])
{
// got a column
return Board[i][j];
}
else if (Board[i][j] == Board[(i+1)%3][j] && Board[i][j] == Board[(i+2)%3][j])
{
// got a row
return Board[i][j];
}
else if (i == j && Board[i][j] == Board[(i+1)%3][(j+1)%3]
&& Board[i][j] == Board[(i+2)%3][(j+2)%3])
{
// got the forward diagonal
return Board[i][j];
}
else if (i+j == 2 && Board[i][j] == Board[(i+2)%3][(j+1)%3]
&& Board[i][j] == Board[(i+1)%3][(j+2)%3])
{
// got the reverse diagonal
return Board[i][j];
}
else {
// got nothing
return 0;
}
Avoid a lot of printing! Better use one structure for the game, for example a board - which is char board[][] or better char** Board if you want a dynamic game. And print the whole board once.
Instead of next code:
printf("P1 start \n");
scanf("%d",&x);
markBoard(x,o,array);
printf("P2 go on\n");
scanf("%d", &o);
markBoard(x,o,array);
Make something like this:
int player = 1;
char row, col;
player = (player % 2) ? 1 : 2;
scanf("%c %c", &row, &col);
markBoard(row, col, board);
Like that you don't need to duplicate a same code and it is automatic knows each turn, who's turn now.
Instead of next code:
if (checkForWin(array) == 1)
printf("P1 won\n");
if (checkForWin(array) == 2)
printf("P2 won\n");
if (checkForWin(array) == 3)
printf("draw \n");
Connect some conditions, like that:
if (checkForWin(array) == 1 || checkForWin(array) == 2) {
printf("Congratulations %c!\n", winner);
} else {
printf("Game ends in a draw.\n");
}
To make more "beauty" code, you can added a structs which will manage the whole game, for example:
typedef struct {
int size;
int **board; // the board
/* scores of all options */
int *rowScores;
int *colScores;
int topLeftBottomRightDiagonalScores;
int topRightBottomLeftDiagonalScores;
} Game;
typedef struct { // position on the board
int x;
int y;
} Position;
Your void markBoard (int x, int o, char array[]) function makes to much iterations to print the whole board. Better create the whole board once and after that run on the whole board.

Related

error in finding no. of vowels in a string

//schecking no of vowels in a string.
#include <stdio.h>
#include <string.h>
void printstring();
int main() {
char sai[8]; //allows 8 charecters.
char a,e,j,o,u; //I have used j as i have already used i for iteration
fgets(sai, 8, stdin); //going to enter my name
char *ptr = sai; ///setting pointer for string
int i,t = 0;
for(i = 0;i <= 7; i++){
if(*(ptr+i) == a) || (*(ptr+i) == e) || (*(ptr+i) == j) || (*(ptr + i) == o) || (*(ptr + i) == u){
t = t+1;
}
else {
t = t;
}
}
printf("%d", t);
}
OUTPUT:
The compiler generated an error:
jill.c: In function 'main':
jill.c:12:23: error: expected expression before '||' token
if(*(ptr+i) == a) || (*(ptr+i) == e) || (*(ptr+i) == j) || (*(ptr + i) == o) || (*(ptr + i) == u){
^~
I expected the number of vowels as output, but an error has occured. Where am I going wrong?
Below listed points are incorrect in your code
Englobe the full condition between brackets in your if condition is missing
Single quotes are missing for character in your if statements. please go through here more explanation.
As comment from  Ted Lyngmo, Craig Estey a,e,j,o,u are uninitialized.
if (*(ptr + i) == a) ||(*(ptr + i) == e) || (*(ptr + i) == j) || (*(ptr + i) == o) || (*(ptr + i) == u)
changed to
if((ptr[i] == 'a') || (ptr[i] == 'e') || (ptr[i] == 'j') || (ptr[i] == 'o') || (ptr[i] == 'u'))
code
//schecking no of vowels in a string.
#include <stdio.h>
#include <string.h>
void printstring();
int main()
{
char sai[8];//allows 8 charecters.
char a,e,j,o,u; //I have used j as i have already used i for iteration
fgets(sai, 8, stdin); //going to enter my name
char *ptr = sai; ///setting pointer for string
int i,t = 0;
for(i = 0;i <= 7; i++)
{
if((ptr[i] == 'a') ||
(ptr[i] == 'e') ||
(ptr[i] == 'j') ||
(ptr[i] == 'o') ||
(ptr[i] == 'u'))
{
t = t+1;
}
else
{
t = t;
}
}
printf("%d", t);
}
Link for below Output:
apple
2

Segmentation fault when there is just one value as input

My code seems to be working fine, but I get a Segmentation fault when there is just one value as input. It should print a square shape based on a number as character input.
test case : ["2", "2"]
"oo\noo\n"
test case: ["", ""]
""
test case : ["2"]
SIGSEGV (signal 11)
#include <string.h>
#include <stdlib.h>
void my_square(int *x, int *y)
{
int i , j;
if (*x == 0 || *y == 0) {
printf("");
}
else{
for(i = 0; i < *x; i++){
for(j = 0; j < *y; j++){
if(*x<=2 && j == 0){
printf("o");
}else if(*x<=2 && j == 1){
printf("o\n");
}else if(*y<=2 && i == 0){
printf("o");
}else if(*y<=2 && i == 1){
printf("o\n");
}else{
//printf(" i: %d, j: %d ", i, j);
if(i == 0 && j == 0 || i == *y-1 && j == 0 || i == 0 && j == *x-1 || i == *y-1 && j == *x-1){
printf("o");
}
if(i >= 1 && j == 0 && i != *y-1) {
printf("|");
}
if(i >= 1 && j == *x-1 && i != *y-1) {
printf("|");
}
if(i == 0 && j >= 1 && j != *y-1|| i == *x-1 && j >= 1 && j != *y-1){
printf("-");
}
if(i >= 1 && j >= 1 && i < *x-1 && j < *y-1){
printf(" ");
}
if(j == *x-1){
printf("\n");
}
}
//printf("> %d, %d", i, j);
}
}
}
}
int main(int ac, char **av)
{
int x = atoi(av[1]);
int y = atoi(av[2]);
my_square(&x, &y);
return 0;
}```
You should always check ac before accessing av, otherwise it may lead to undefined behaviour (and cause a segmentation fault).
That's how you could do it (the first value is always the program file name):
int main(int ac, char **av)
{
int x, y;
if (ac <= 3)
{
x = atoi(av[1]);
y = x; // if there's only one argument, we use it for both x and y
if (ac == 3)
{
y = atoi(av[2]);
}
my_square(&x, &y);
}
return 0;
}

Logical errors in Tic-Tac-Toe game

I am trying to make a Tic-Tac-Toe game. I have written the code which I believe should work fine, but instead it is throwing logical errors.
#include <stdio.h>
#define size 9
char game_logic();
int game_win();
char array[size] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
int main()
{
printf("\n\t\t Welcome to Tic-Tac-Toe game\n\n");
printf(" In this game, there will be two players taking turns for their moves\n\n");
printf("\t\t Player 1 = 'X' and Player 2 = 'O'\n\n");
for (int i = 0; i < size; i++)
{
printf("\t%c", array[i]);
if (array[i] == '1' || array[i] == '2' || array[i] == '4' ||
array[i] == '5' || array[i] == '7' || array[i] == '8')
{
printf(" |");
}
if (array[i] == '3' || array[i] == '6')
{
printf("\n -----------------------\n");
}
}
printf("\n\n");
do
{
game_logic();
} while (game_win() != 1 || game_win() != 2 || game_win != 3);
if (game_win() == 1)
{
printf("\nThe Player 1 has won the game\n");
}
else if (game_win() == 2)
{
printf("\nThe Player 2 has won the game\n");
}
else if (game_win() == 3)
{
printf("\nThe game is draw\n");
}
return 0;
}
char game_logic()
{
int n, m;
for (int i = 0; i < size; i++)
{
if (i % 2 == 0)
{
printf("Player 1, Please select the number = ");
scanf("%d", &n);
if (n > 0 && n < 10)
{
array[n] = 'X';
return array[n];
break;
}
}
else if (i % 2 != 0)
{
printf("Player 2, Please select the number = ");
scanf("%d", &m);
if (n > 0 && n < 10)
{
array[n] = 'O';
return array[n];
break;
}
}
}
}
int game_win()
{
game_logic();
if (array[0] == array[1] == array[2] == 'X' ||
array[2] == array[5] == array[8] == 'X' ||
array[6] == array[7] == array[8] == 'X' ||
array[0] == array[3] == array[6] == 'X' ||
array[0] == array[4] == array[8] == 'X' ||
array[2] == array[4] == array[6] == 'X' ||
array[1] == array[4] == array[7] == 'X' ||
array[3] == array[4] == array[5] == 'X')
{
return 1;
}
else
if (array[0] == array[1] == array[2] == 'O' ||
array[2] == array[5] == array[8] == 'O' ||
array[6] == array[7] == array[8] == 'O' ||
array[0] == array[3] == array[6] == 'O' ||
array[0] == array[4] == array[8] == 'O' ||
array[2] == array[4] == array[6] == 'O' ||
array[1] == array[4] == array[7] == 'O' ||
array[3] == array[4] == array[5] == 'O')
{
return 2;
}
else
{
return 3;
}
}
The basic plan was to execute game_logic which will decide how the game will run, it will take input from the user in the form of integers between 1 and 9. The number selected by the user will be replaced by X in the global array if player 1 inputs it, and will be replaced by O if player 2 selects it.
The results of game_logic is to be sent to the game_win which will determine if the game has been won or not by returning the values to the main function.
But when I ran the code, a loop occurs which says "Player 1, Please select the number = ", and this keeps on going by taking infinite input.
I have tried debugging it, but it is unable to help me. So can please suggest solutions for the logic made, or if my logic is correct.
The output:
Welcome to Tic-Tac-Toe game
In this game, there will be two players taking turns for their moves
Player 1 = 'X' and Player 2 = 'O'
1 | 2 | 3
-----------------------
4 | 5 | 6
-----------------------
7 | 8 | 9
Player 1, Please select the number = 3
Player 1, Please select the number = 2
Player 1, Please select the number = 3
Player 1, Please select the number = 4
Player 1, Please select the number = 3
Player 1, Please select the number = 2
Player 1, Please select the number = 2
Player 1, Please select the number = 3
Player 1, Please select the number = 4
and this keeps on going.
There are at least these major problems:
the test in the do ... while loop is incorrect: the loop iterates while (game_win() != 1 || game_win() != 2 || game_win != 3)... the third test compare the function name with 3 not return value of the function call, and even if you fix this problem, the test is always true since game_win() cannot be both 1 and 2 and 3. You should instead write:
do {
game_logic();
} while (game_win() != 0);
the tests in game_win() are incorrect: array[0] == array[1] == array[2] == 'X' should be written:
(array[0] == 'X' && array[1] == 'X' && array[2] == 'X')
game_win() does not properly test for a draw and never returns 0 in other cases.
if you call game_logic() in the loop, game_win() should not also call game_logic(). It would make sense for game_logic() to return the game_win() result, which would simplify the loop as:
while (game_logic())
continue;
the slot modified in game_logic() is incorrect: the number n is between 1 and 9, but the array elements start at 0 so you should modify array[n - 1].
the slot for player 2 is read into m, whereas the code uses n afterwards.
it would be more user friendly to redisplay the board before each turn.
Here is a modified version:
#include <stdio.h>
#define SIZE 9
int game_win(void);
int game_logic(int i);
char array[SIZE] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
void display_board(void) {
printf("\n ");
for (int i = 1; i <= SIZE; i++) {
printf(" %c", array[i - 1]);
if (i == 1 || i == 2 || i == 4 || i == 5 || i == 7 || i == 8) {
printf(" |");
}
if (i == 3 || i == 6) {
printf("\n -----------------------\n ");
}
}
printf("\n\n");
}
int game_win(void) {
if ((array[0] == 'X' && array[1] == 'X' && array[2] == 'X') ||
(array[3] == 'X' && array[4] == 'X' && array[5] == 'X') ||
(array[6] == 'X' && array[7] == 'X' && array[8] == 'X') ||
(array[0] == 'X' && array[3] == 'X' && array[6] == 'X') ||
(array[1] == 'X' && array[4] == 'X' && array[7] == 'X') ||
(array[2] == 'X' && array[5] == 'X' && array[8] == 'X') ||
(array[0] == 'X' && array[4] == 'X' && array[8] == 'X') ||
(array[2] == 'X' && array[4] == 'X' && array[6] == 'X')) {
return 1;
}
if ((array[0] == 'O' && array[1] == 'O' && array[2] == 'O') ||
(array[3] == 'O' && array[4] == 'O' && array[5] == 'O') ||
(array[6] == 'O' && array[7] == 'O' && array[8] == 'O') ||
(array[0] == 'O' && array[3] == 'O' && array[6] == 'O') ||
(array[1] == 'O' && array[4] == 'O' && array[7] == 'O') ||
(array[2] == 'O' && array[5] == 'O' && array[8] == 'O') ||
(array[0] == 'O' && array[4] == 'O' && array[8] == 'O') ||
(array[2] == 'O' && array[4] == 'O' && array[6] == 'O')) {
return 2;
}
for (int i = 1; i <= SIZE; i++) {
if (array[i - 1] == '0' + i)
return 0;
}
return 3;
}
int game_logic(int i) {
for (;;) {
char buf[32];
int player, n;
char mark;
if (i % 2 == 0) {
player = 1;
mark = 'X';
} else {
player = 2;
mark = 'O';
}
printf("Player %d, Please select the number = ", player);
if (!fgets(buf, sizeof buf, stdin)) {
/* end of file reached: abort */
return -1;
}
if (sscanf(buf, "%d", &n) != 1 || n < 1 || n > 9) {
printf("please enter a number between 1 and 9\n");
continue;
}
if (array[n - 1] != '0' + n) {
printf("slot %d is already played\n", n);
continue;
}
array[n - 1] = mark;
return game_win();
}
}
int main() {
printf("\n\t\t Welcome to Tic-Tac-Toe game\n\n");
printf(" In this game, there will be two players taking turns for their moves\n\n");
printf("\t\t Player 1 = 'X' and Player 2 = 'O'\n\n");
for (int i = 0; i < SIZE; i++) {
display_board();
if (game_logic(i) != 0)
break;
}
switch (game_win()) {
case 0:
printf("\nThe game was aborted\n");
break;
case 1:
display_board();
printf("\nThe Player 1 has won the game\n");
break;
case 2:
display_board();
printf("\nThe Player 2 has won the game\n");
break;
case 3:
display_board();
printf("\nThe game is draw\n");
break;
}
return 0;
}
In the loop inside the game_logic function, it returns after Player1 entered a valid number. And then game_logic is called in a loop, so i gets never increased and this causes the endless loop.

Passing an updated Char array back through pointers

I'm trying to pass back an updated char array to the original main() function, however when i try to copy over the array with a pointer before it it gives me "Char " differs in levels of indirection from char() [15]'
This is a ISBN validator program.
Here it is:
int main(void)
{
int divisible;
char choice, trash;
char code[15];
do
{
printf("Enter an ISBN (book) number:\n");
fgets(code, 15, stdin);
printf("The ISBN entered is:%s\n", code);
divisible = testISBN(&code);
if (divisible == 1)
printf("\n\n\tValid ISBN Number\n");
else
printf("\n\n\tInvalid ISBN Number\n");
printf("\nDo you wish to continue? (Y/N)\n");
choice = getchar();
trash = getchar();
} while (toupper(choice) != 'N');
return 0;
}
int testISBN(char *code)
{
int i;
int sum = 0;
int weight = 10;
char codefinal[10];
int x = 0;
for (i = 0; i<15; i++)
{
int chVal;
if ((i == 9) && (toupper(code[i]) == 'X'))
{
printf("%c",code[i]);
chVal = 10;
}
else
{
chVal = code[i] - '0';
}
if (chVal == 0 || chVal == 1 || chVal == 2 || chVal == 3 || chVal == 4 || chVal == 5 || chVal == 6 || chVal == 7 || chVal == 8 || chVal == 9) {
char y = (char)chVal;
codefinal[x] = y;
x++;
}
sum += chVal * weight;
weight--;
}
printf("sum is %d", sum);
for (i = 0; i < 15; i++) {
*code[i] = codefinal[i];
printf("%c", code);
}
return (sum % 11) == 0;
}
At the very bottom where i said *code[i] = codefinal[i] is where i get the issue. I'm just trying to pass back by pointer my new updated array of numbers to my main.
Do following changes in your code:
Change prototype of function int testISBN(char* code) to int testISBN(char code[])
Change calling from testISBN(&code); to testISBN(code);
Change line *code[i] = codefinal[i]; to code[i] = codefinal[i];
In line printf("%c", code); you are printing not the value but the address of code[]. So change it to printf("%c", code[i]);. Note that code[] contains some non printable characters also.
Suggestion: You can change line if (chVal == 0 || chVal == 1 || chVal == 2 || chVal == 3 || chVal == 4 || chVal == 5 || chVal == 6 || chVal == 7 || chVal == 8 || chVal == 9) to if((chVal >= 0) && (chVal <= 9)) for simplicity.
Just pass code as is it will decay into pointer.
char code[15];
divisible = testISBN(code);
You may want to change testISBN signature to
int testISBN(char code[15]);
This way you have a higher chances to get compiler warning if you mess up indices.
Simple example:
#include <stdio.h>
void func(char arr[3]) {
arr[0] = 'H';
arr[1] = 'i';
arr[2] = 0;
}
int main() {
char arr[3] = {0};
func(arr);
printf("%s", arr);
}
Prints "Hi"
As commenters mentioned your code has other issues such as memory out of bounds access. To ease your life spend some time with your compiler's manual and learn how to turn on all the warnings, they indicate code issues most of the time.

I am wondering why I get a random integer as my output in this program

This program is designed to take 3 integers and arrange them in ascending order. When I input a combination such as "12 8 2", I get an output of "1995099040 8 12". Any help with why i'm getting this answer?
#include <stdio.h>
#include <stdlib.h>
int findBig(int d, int e, int f) {
if ((d >= e) && (d >= f)) {
return d;
} else
if ((e >= d) && (e >= f)) {
return e;
} else
if ((f >= e) && (f >= d)) {
return f;
}
}
int main(void) {
const int MAX_NUM = 3;
int userArray[MAX_NUM];
int bigNum;
int midNum;
int smallNum;
int j = 0;
int a;
int b;
int c;
printf("Please enter three integers separated by spaces:\n");
for (j = 0; j < MAX_NUM; ++j) {
scanf("%d", &userArray[j]);
}
a = userArray[0];
b = userArray[1];
c = userArray[2];
bigNum = findBig(a, b, c);
if (bigNum == a) {
midNum = findBig(0, b, c);
} else
if (bigNum == b) {
midNum = findBig(a, 0, c);
} else
if (bigNum == c) {
midNum = findBig(a, b, 0);
}
if ((midNum == a) && (bigNum == b)) {
smallNum = c;
} else
if ((midNum == b) && (bigNum == c)) {
smallNum = a;
} else
if ((midNum == c) && (bigNum == a)) {
smallNum = b;
}
printf("%d %d %d\n", smallNum, midNum, bigNum);
return 0;
}
smallNum stays with the junk value it gets when it is created, because you didn't cover all the cases for the values possible for bigNum and midNum, so it doesn't get assigned a value in certain cases - like the one you experienced the problem with - and stays uninitialized.
Make sure to check all the possible cases:
if((midNum == a) && (bigNum == b)){ smallNum = c; }
else if((midNum == b) && (bigNum == c)){ smallNum = a; }
else if((midNum == c) && (bigNum == a)){ smallNum = b; }
else if((midNum == b) && (bigNum == a)){ smallNum = c; }
else if((midNum == c) && (bigNum == b)){ smallNum = a; }
else if((midNum == a) && (bigNum == c)){ smallNum = b; }
Also, consider using built-in functions, to save time and code - you have the max and min function right there to help you.
To find the maximum of three numbers you may use max(max(a, b), c) - so we can shorten the code to
smallNum = min(min(a, b), c);
bigNum = max(max(a, b), c);
midNum = (a + b + c) - smallNum - bigNum;
(This will halve the code and render findBig unnecessary)
There are 6 cases to consider for determining smallNum.
if((midNum == a) && (bigNum == b) || ((midNum == b) && (bigNum == a))){
smallNum = c;
}
else if((midNum == b) && (bigNum == c) || ((midNum == c) && (bigNum == b))){
smallNum = a;
}
else if((midNum == c) && (bigNum == a) || ((midNum == a) && (bigNum == c))){
smallNum = b;
}
The junk is due to the missing cases.
You get garbage output because your code invokes undefined behavior:
for the input 12 8 2, the case (midNum == b) && (bigNum == a) is not handled in the code and smallNum stays uninitialized.
You can simplify your code by rearranging the array with 3 tests and swaps:
#include <stdio.h>
int main(void) {
const int MAX_NUM = 3;
int userArray[MAX_NUM];
int x;
printf("Please enter three integers separated by spaces:\n");
for (int j = 0; j < MAX_NUM; ++j) {
if (scanf("%d", &userArray[j]) != 1)
exit(1);
}
if (userArray[0] > userArray[1]) {
x = userArray[0]; userArray[0] = userArray[1]; userArray[1] = x;
}
if (userArray[1] > userArray[2]) {
x = userArray[1]; userArray[1] = userArray[2]; userArray[2] = x;
}
if (userArray[0] > userArray[1]) {
x = userArray[0]; userArray[0] = userArray[1]; userArray[1] = x;
}
printf("%d %d %d\n", userArray[0], userArray[1], userArray[2]);
return 0;
}
I agree with the other answers - your code doesn't take into account all 6 possibilities in which the values could be ordered.
A possible way to fix this: first, modify your "find maximum" function so it returns an index instead of a value:
int findBig(int d, int e, int f) {
if ((d >= e) && (d >= f)) {
return 0; // index of largest element is 0
} else
if ((e >= d) && (e >= f)) {
return 1; // index of largest element is 1
} else
if ((f >= e) && (f >= d)) {
return 2; // index of largest element is 2
}
}
Then, find which number is big, small and median:
bigIndex = findBig(a, b, c);
smallIndex = findBig(-a, -b, -c); // a hack to find the minimum instead of maximum
if (bigIndex == smallIndex)
{
// Edge case - all numbers are equal
// Doesn't matter which index is which; just choose 3 different ones
bigIndex = 0;
midIndex = 1;
smallIndex = 2;
}
else
{
// Choose the index that is neither big nor small
midIndex = 3 - bigIndex - smallIndex;
}
Then print them:
printf("%d %d %d\n", userArray[smallIndex], userArray[midIndex], userArray[bigIndex]);
Here it helps that you have an array. Otherwise, it would still be possible to convert an index to a value bit it would be ugly:
printf("%d %d %d\n",
smallIndex == 0 ? a : smallIndex == 1 ? b : c,
midIndex == 0 ? a : midIndex == 1 ? b : c,
bigIndex == 0 ? a : bigIndex == 1 ? b : c);

Resources