Taking user input while running while loop - c

So I am making stopwatch with c but I wanted to be able to take user input while the stopwatch is running.
`
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#include "mylib/mylib.h"
void Delay(ms){
clock_t timeDelay = ms + clock();
while(timeDelay > clock());
}
void PrintData(int hour, int minute, int second){
printf(" %d:%d:%d \n", hour, minute, second);
}
void StopWatch(int hour, int minute, int second, int flag, int input){
while(flag == 0){
if (minute > 59){
minute = 0;
hour++;
}
if(second > 59 ){
second = 0;
minute++;
}
system("clear");
PrintData(hour, minute, second);
Delay(1000000);
second++;
}
}
int main(void){
int s0 = 0, s1 = 0, S0 = 0, S1 = 0, b1 = 0, b2 = 0, O0 = 0, O1 = 0;
int hour = 0, minute = 0, second = 0, flag = 0;
int input;
while(1){
if ((S0 == 0 && S1 == 0)){
if(b1 == 1 && b2 == 0){
flag = 0;
system("clear");
}
else if(b1 == 0 && b2 == 1){
flag = 1;
system("clear");
}
else if(b1 == 1 && b2 == 1){
flag = 1;
system("clear");
}
else if(b1 == 0 && b2 == 0){
flag = 1;
system("clear");
}
printf("Current state %d %d\n", S0, S1);
}
else if((S0 == 0 && S1 == 1)){
if(b1 == 1 && b2 == 0){
flag = 0;
system("clear");
PrintData(hour, minute, second);
}
else if(b1 == 0 && b2 == 1){
flag = 1;
system("clear");
PrintData(hour, minute, second);
}
else if(b1 == 1 && b2 == 1){
flag = 1;
system("clear");
PrintData(hour, minute, second);
}
else if(b1 == 0 && b2 == 0){
system("clear");
PrintData(hour, minute, second);
}
printf("Current state %d %d\n", S0, S1);
}
else if((S0 == 1 && S1 == 0)){
if(b1 == 1 && b2 == 0){
flag = 0;
StopWatch(hour, minute, second, flag, input);
}
else if(b1 == 0 && b2 == 1){
flag = 1;
break;
}
else if(b1 == 1 && b2 == 1){
flag = 0;
}
else if(b1 == 0 && b2 == 0){
PrintData(hour, minute, second);
}
printf("Current state %d %d\n", S0, S1);
}
else if((S0 == 1 && S1 == 1)){
if(b1 == 1 && b2 == 0){
flag = 0;
system("clear");
}
else if(b1 == 0 && b2 == 1){
flag = 0;
system("clear");
}
else if(b1 == 1 && b2 == 1){
flag = 0;
system("clear");
PrintData(hour, minute, second);
}
else if(b1 == 0 && b2 == 0){
flag = 0;
}
}
b1 = 0;
b2 = 0;
printf("Insert input(1/2/3(both) \n");
scanf("%d", &input);
if(input == 1){
b1 = 1;
b2 = 0;
}
else if(input == 2){
b1 = 0;
b2 = 1;
}
else if(input == 3){
b1 = 1;
b2 = 1;
}
else if(input == 0){
b1 = 0;
b2 = 0;
}
else{
input = 0;
}
states(s0, s1, b1, b2, &S0, &S1);
s0 = S0;
s1 = S1;
}
return 0;
}
`
I wanted to be able showing the current state and making an input while the stopwatch is running.
It should be showing the insert input and the current state while the stopwatch is counting.
I've tried to put the input on stopwatch function but it wouldn't work.
I've been tried many ways and comes up with nothing. I'm completely have no idea how to do it.

Related

How to reset array in my tic tac toe game

I'm new to C and I'm trying to make a tic-tac-toe game for my college project and I'm struggling on how to reset my array in my game.
Every time I play again it does not reset the array. Can anyone help me with this?
Here is the code:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
char space[3][3] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'}
};
void board();
int checkWin();
int game();
void reset();
int main(){
int choice = -1;
do{
printf("\n\n\n\n\n\n\n\t\t\t ================\n");
printf("\t\t\t Tic Tac Toe\n");
printf("\t\t\t ================\n");
printf("\t\t -----------Menu-----------\n\n");
printf("\t\t 1. Play\n");
printf("\t\t 2. Exit\n");
scanf("%d", &choice);
switch(choice){
case 1: game();
break;
case 2: printf("Goodbye!!");
exit(0);
break;
default: printf(".......Wrong Key !.......Try Again!......");
break;
}
}while(choice != 0);
}
int game(){
int player = 1, i, choice;
char mark;
do
{
system("cls");
board();
player = (player % 2) ? 1 : 2;
printf("Player %d, enter a number: ", player);
scanf("%d", &choice);
mark = (player == 1) ? 'X' : 'O';
if (choice == 1)
space[0][0] = mark;
else if (choice == 2)
space[0][1] = mark;
else if (choice == 3)
space[0][2] = mark;
else if (choice == 4)
space[1][0] = mark;
else if (choice == 5)
space[1][1] = mark;
else if (choice == 6)
space[1][2] = mark;
else if (choice == 7)
space[2][0] = mark;
else if (choice == 8)
space[2][1] = mark;
else if (choice == 9)
space[2][2] = mark;
else
{
printf("Invalid move ");
player--;
getch();
}
i = checkWin();
player++;
}while (i == - 1);
board();
reset();
if (i == 1)
printf("==>\aPlayer %d win \n\n", --player);
else
printf("==>\aGame draw\n\n");
getch();
return 0;
}
int checkWin(){
if (space[0][0] == space[0][1] && space[0][1] == space[0][2])
return 1;
else if (space[1][0] == space[1][1] && space[1][1] == space[1][2])
return 1;
else if (space[2][0] == space[2][1] && space[2][1] == space[2][2])
return 1;
else if (space[0][0] == space[1][0] && space[1][0] == space[2][0])
return 1;
else if (space[0][1] == space[1][1] && space[1][1] == space[2][1])
return 1;
else if (space[0][2] == space[1][2] && space[1][2] == space[2][2])
return 1;
else if (space[0][0] == space[1][1] && space[1][1] == space[2][2])
return 1;
else if (space[0][2] == space[1][1] && space[1][1] == space[2][0])
return 1;
else if (space[0][0] != space[0][0] && space[0][1] != space[0][1] && space[0][2] != space[0][2] &&
space[1][0] != space[1][0] && space[1][1] != space[1][1] && space[1][2] != space[1][2] && space[2][0]
!= space[2][0] && space[2][1] != space[2][1] && space[2][2] != space[2][1])
return 0;
else
return - 1;
}
void reset(){
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
space[i][j] = 0;
}
}
}
void board(){
system("cls");
printf("\n\n\tTic Tac Toe\n\n");
printf("Player 1 (X) - Player 2 (O)\n\n\n");
printf(" | | \n");
printf(" %c | %c | %c \n", space[0][0], space[0][1], space[0][2]);
printf("_____|_____|_____\n");
printf(" | | \n");
printf(" %c | %c | %c \n", space[1][0], space[1][1], space[1][2]);
printf("_____|_____|_____\n");
printf(" | | \n");
printf(" %c | %c | %c \n", space[2][0], space[2][1], space[2][2]);
printf(" | | \n\n");
}
I tried using for loop but it does not work; how can I solve this?
void reset(){
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
space[i][j] = 0;
}
}
}
Your reset function is filling the entire 3x3 board matrix with zeros; these represent the nul character, not the character representing the '0' digit. Those nul characters aren't printed (and cannot be), so the board looks 'wrong' after a reset.
However, simply changing the space[i][j] = 0; line to space[i][j] = '0'; won't work! Although you will then initially see a board full of 0 digits, the way your checkWin() function works will then ensure that "Player 1" will have won the new game immediately after their first move, because there will already be rows/columns/diagonals of three identical characters.
So, to get the original ('1' thru '9') display, write your reset() function as below. (Note that the C Standard requires that the characters representing the numerical digits be in order and contiguous, so adding a value of 1 thru 9 to the '0' character will yield the appropriate digit character.)
void reset()
{
int number = 1;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
space[i][j] = number++ + '0';
}
}
}
Alternatively, you can just declare and initialize a new 'board array' with the data in it, then just use memcpy to rest the space array with the contents of that:
#include <string.h> // For "memcpy"
void reset()
{
char empty[3][3] = { {'1','2','3'}, {'4','5','6'}, {'7','8','9'} };
memcpy(space, empty, sizeof(space));
}
Note, also that all the tests in the following statement are wrong:
else if (space[0][0] != space[0][0] && space[0][1] != space[0][1] && space[0][2] != space[0][2] &&
space[1][0] != space[1][0] && space[1][1] != space[1][1] && space[1][2] != space[1][2] && space[2][0]
!= space[2][0] && space[2][1] != space[2][1] && space[2][2] != space[2][1])
Each one of these is testing if an element is not equal to itself. This can never be true, so that else if block (the return 0; line) is never executed. But you don't actually need it, so you can just delete that block.

How to write a program that takes 3 inputs by user F0, F1 and fmax, and outputs all prime Fibonnaci numbers?

This code skips the always the first 2 fibonnaci numbers which are prime (F0 and F1)
I need to write a generalized Fibonnaci sequence that are also prime.
where Fn​=Fn−1​+Fn−2, I know my problem is in the loop, but I am not figuring it out.
#include <stdio.h>
#include <stdlib.h>
#define false 0
#define true 1
int main(int argc, char **argv)
{
int NN, PN, i, terms;
int F0;
int F1;
int Fmax;
char *p;
terms = Fmax = strtol(argv[3], &p, 10);
F0 = strtol(argv[1], &p, 10);;
F1 = strtol(argv[2], &p, 10);
F0 = strtol(argv[1], &p, 10);
if (*p != '\0')
{
return 1;
}
F1 = strtol(argv[2], &p, 10);
if (*p != '\0')
{
return 1;
}
Fmax = strtol(argv[3], &p, 10);
if (*p != '\0')
{
return 1;
}
if (argc != 4)
{
printf("Error: Please enter only 3 values, for F0, F1 and Fmax\n");
return 1;
}
if (F0 < 1 || F1 < 1 || Fmax < 1)
{
printf("Error: Please put only positive values\n");
}
if (F0 > F1)
{
printf("Error: F0 can not be bigger than F1\n");
}
if (Fmax < F1)
{
printf("Error: Fmax can`t be less than F1\n");
}
if (F0 < 1 || Fmax > 1000000)
{
printf("Error: Please enter a value between 1 and 1000000\n");
return 1;
}
I am sure the problem is in here, but I have tried to set terms as Fmax, and I actually saw some codes online that is supposed to have the same purpose.
else
{
if (F1 == 2)
{
printf("2\n");
}
for(i = 0; i < terms; i++)
{
NN = F0 + F1;
F0 = F1;
F1 = NN;
for(PN = 3; PN <= NN; PN++)
{
if(PN == NN)
printf("%d\n", NN);
if (NN > Fmax)
break;
if (NN % PN == 0)
break;
}
}
}
return 0;
}

writing a prime factorization program C

I am trying to write a program that shows the results of prime factorization as below:
prompt: Input a positive integer
result examples:
100 = 2^2*5^2
It is a composite integer !
13 = 13
It is a prime number !
I tried to write it only with the basic loops, not using sophisticated techniques because it was for beginner's class. The problem is that when I enter 100 as an input, the result is just
100 =
being printed and the program stops there. Other than that, it gives me results I intended. Can anyone help me find what part of this code is the problem?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int inputNumber (int* input);
int primeFactors (int input);
int main (void) {
int input;
while ( 1 ) {
inputNumber (&input);
primeFactors (input);
}
return 0;
}
int inputNumber (int* input){
printf("\nInput a positive integer : ");
scanf("%d", input);
if(*input == 0){
printf("\n End of program");
exit(0);
}
return;
}
int primeFactors (int input){
int cnt = 0, i = 3, cnt_sum;
printf("%d = ", input);
if(input > 0){
while ( input % 2 == 0){
cnt++;}
if(cnt == 1){
printf("%d",2);}
else if( cnt > 0 && cnt != 1){
printf("%d^%d",2,cnt);
}
cnt_sum += cnt;
for ( ; i <= sqrt(input); i = i+2){
cnt = 0;
while(input % i == 0){
cnt++;
input /= i;
}
if(cnt == 1){
printf("%d",i);
}
else if( cnt > 0 && cnt != 1){
printf("%d^%d",i,cnt);
}
cnt_sum += cnt;
}
if(cnt_sum > 1){
printf("\nIt is a composite number !\n");
}
else{
printf("%d\nIt is a prime number !\n",input);
}
}
else{
printf("\nIt is an invalid number !\n");
}
}
There were few bugs.
while ( input % 2 == 0){cnt++;} loops infinitely if input is even( #Marian )
if(input > 1){ instead of if(input > 0){. since 1 is neither prime nor composite.
Corrected function:
int primeFactors (int input){
int cnt = 0, i = 3, cnt_sum;
printf("%d = ", input);
if(input > 1){
while ( input % 2 == 0){
input/=2;
cnt++;
}
if(cnt == 1){
printf("%d",2);}
else if( cnt > 0 && cnt != 1){
printf("%d^%d",2,cnt);
}
cnt_sum += cnt;
for ( ; i <= sqrt(input); i = i+2){
cnt = 0;
while(input % i == 0){
cnt++;
input /= i;
}
if(cnt == 1){
printf("%d",i);
}
else if( cnt > 0 && cnt != 1){
printf("%d^%d",i,cnt);
}
cnt_sum += cnt;
}
if(cnt_sum > 1){
printf("\nIt is a composite number !\n");
}
else{
printf("%d\nIt is a prime number !\n",input);
}
}
else{
printf("\nIt is an invalid number !\n");
}
}
ideone
You seem to be missing some steps in your algorithm, as well as checking redundant conditions in your primeFactors function.
int cnt = 0, i = 3, cnt_sum;
Because these won't ever be negative, you can change the type to unsigned.
while ( input % 2 == 0){
cnt++;
}
This while statement will loop infinitely if input is odd, because nothing is done to change input. You can add input = input / 2; to stop this.
if(cnt == 1){
printf("%d",2);}
else if( cnt > 0 && cnt != 1){
printf("%d^%d",2,cnt);
}
The else if expression can be reduced to an else statement, because unsigned variables are always greater than 0 and we already know cnt != 1, otherwise the first statement would be triggered.
while(input % i == 0){
cnt++;
input /= i;
}
The while statement is all good here, how peculiar. :P
if(cnt == 1){
printf("%d",i);
}
else if( cnt > 0 && cnt != 1){
printf("%d^%d",i,cnt);
}
Same deal here as with the if / else if statements before: change the else if to else.
With these corrections applied (and some style inconsistencies fixed), the function now looks like this:
int primeFactors (int input) {
unsigned cnt = 0, i = 3, cnt_sum;
printf("%d = ", input);
if (input > 0) {
while (input % 2 == 0) {
cnt++;
input /= 2;
}
if (cnt == 1) {
printf("%d", 2);
} else {
printf("%d^%d", 2, cnt);
}
cnt_sum += cnt;
for ( ; i <= sqrt(input); i += 2){
cnt = 0;
while (input % i == 0) {
cnt++;
input /= i;
}
if (cnt == 1) {
printf("%d", i);
} else {
printf("%d^%d", i, cnt);
}
cnt_sum += cnt;
}
if (cnt_sum > 1) {
printf("%d\nIt is a composite number !\n");
} else {
printf("%d\nIt is a prime number !\n",input);
}
}
else{
printf("\nIt is an invalid number !\n");
}
}

Converting Time how can I improve my code? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
Just started programming so any suggestion or constructive criticism would be much appreciated. I'm pretty sure there are ways to shorten this I just don't know how, especially the use of functions.
#include <stdio.h>
#include <stdlib.h>
int input, check = 1, ans;
int menu ();
int convert24(int hour, int min, int sec, int meridiem);
int convert12(int hour, int min, int sec, int meridiem);
int result(int hour, int min, int sec, int meridiem);
void processAnother();
int main()
{
do
{
menu();
processAnother();
system("cls");
}while (ans = 'y');
}
int menu ()
{
int hour, min, sec, meridiem;
printf("[1] Convert to 24-hour notation\n");
printf("[2] Convert to 12-hour notation\n");
printf("[3] Quit\n");
scanf("%d", &input);
switch(input)
{
case 1 :
{
printf("Enter hours (1-12):minute(1-59):seconds(1-59): ");
scanf("%d %d %d", &hour, &min, &sec);
printf("[1] AM or [2] PM: ");
scanf(" %d", &meridiem);
return convert24(hour, min, sec, meridiem);
break;
}
case 2 :
{
printf("Enter hours(1-24):minute(1-59):seconds(1-59): ");
scanf("%d %d %d", &hour, &min, &sec);
printf("[1]AM or [2]PM: ");
scanf(" %d", &meridiem);
return convert12(hour, min, sec, meridiem);
break;
}
default :
{
printf("Goodbye :)");
exit(0);
}
}
}
int convert24(int hour, int min, int sec, int meridiem)
{
if ((hour > 12 || hour < 0))
{
printf("\nError! Invalid Hour\n");
check = 0;
}
if ((min >= 60 || min <0))
{
printf("\nError! Invalid Minute\n");
check = 0;
}
if ((sec >= 60 || sec <0))
{
printf("\nError! Invalid Second\n");
check = 0;
}
if (meridiem > 2 || meridiem < 0)
{
printf("\nError! Invalid Meridiem\n");
check = 0;
}
if (check == 1)
{
if (meridiem == 1)
{
if (hour == 12)
{
hour = 0;
result(hour, min, sec, meridiem);
}
else
{
result(hour, min, sec, meridiem);
}
}
else if (meridiem == 2)
{
if (hour == 12)
{
hour = 12;
result(hour, min, sec, meridiem);
}
else
{
hour+=12;
result(hour, min, sec, meridiem);
}
}
}
processAnother();
}
int convert12(int hour, int min, int sec, int meridiem)
{
if ((hour > 24 || hour < 0))
{
printf("\nError! Invalid Hour\n");
check = 0;
}
if ((min >= 60 || min <0))
{
printf("\nError! Invalid Minute\n");
check = 0;
}
if ((sec >= 60 || sec <0))
{
printf("\nError! Invalid Second\n");
check = 0;
}
if (meridiem > 2 || meridiem < 0)
{
printf("\nError! Invalid Meridiem\n");
check = 0;
}
if (check == 1)
{
if (meridiem == 1)
{
if (hour <= 12)
{
result(hour, min, sec, meridiem);
}
else
{
hour -= 12;
result(hour, min, sec, meridiem);
}
}
else if (meridiem == 2)
{
if (hour <= 12)
{
result(hour, min, sec, meridiem);
}
else
{
hour -= 12;
result(hour, min, sec, meridiem);
}
}
}
processAnother();
}
int result(int hour, int min, int sec, int meridiem)
{
char *x;
int y;
if(meridiem == 1)
{
x = "AM";
}
else if (meridiem == 2)
{
x = "PM";
}
if (input == 1)
{
y = 24;
}
else if (input == 2)
{
y = 12;
}
printf("The %d-hr Notation is : %d:%d:%d %s\n",y, hour, min, sec, x);
return;
}
void processAnother()
{
printf("Process another [y/n]");
scanf("%c", &ans);
return;
}
Thank you very much.
ans, is used as a char but declared as a int, it will work but it's ugly, also don't abuse global variable, input, check and ans can be declared somewhere else and some of them dont even need to be declared.
On convert12() and convert24() you're doing the same thing on the 20 first line, write a function that return 0 if they're an error and 1 otherwise.
I usualy put the main() function at the bottom of my file it allow me to not prototype every other function on the file
Instead of passing hour, min, sec and meridiem everytime you call most of your functions, create a struct with every element inside and pass a pointer of it.
main() should be declared like this main(void) see here for more information
for this one i'm gona use multiple steps
first:
int convert12(int hour, int min, int sec, int meridiem)
{
if ((hour > 24 || hour < 0))
{
printf("\nError! Invalid Hour\n");
check = 0;
}
if ((min >= 60 || min <0))
{
printf("\nError! Invalid Minute\n");
check = 0;
}
if ((sec >= 60 || sec <0))
{
printf("\nError! Invalid Second\n");
check = 0;
}
if (meridiem > 2 || meridiem < 0)
{
printf("\nError! Invalid Meridiem\n");
check = 0;
}
if (check == 1)
{
if (meridiem == 1)
{
if (hour <= 12)
{
result(hour, min, sec, meridiem);
}
else
{
hour -= 12;
result(hour, min, sec, meridiem);
}
}
else if (meridiem == 2)
{
if (hour <= 12)
{
result(hour, min, sec, meridiem);
}
else
{
hour -= 12;
result(hour, min, sec, meridiem);
}
}
}
processAnother();
}
can become:
int convert12(my_time_t *time, int input)
{
if (are_time_correct(time, input))
{
if (time->meridiem == 1)
{
if (time->hour <= 12)
{
}
else
{
time->hour -= 12;
}
}
else if (time->meridiem == 2)
{
if (time->hour <= 12)
{
}
else
{
time->hour -= 12;
}
}
}
result(time, input);
processAnother();
}
I followed my previous advice and moved the call of result at the end
I know it won't work like this but you can now write it like that:
int convert12(my_time_t *time, int input)
{
if (are_time_correct(time, input))
{
if (time->meridiem == 1 && time->hour > 12)
{
time->hour -= 12;
}
else if (time->meridiem == 2 && time->hour > 12)
{
time->hour -= 12;
}
}
result(time, input);
processAnother();
}
just before we tested if meridiem was between 1 and 2 so we can write this function like this
int convert12(my_time_t *time, int input)
{
if (are_time_correct(time, input) && time->hour > 12)
{
time->hour -= 12;
}
result(time, input);
processAnother();
}
do the same process for convert24()
If you followed all of my instruction you should have something like this:
#include <stdio.h>
#include <stdlib.h>
// time_t aleardy exist so I used my_time_t instead
typedef struct my_time_s
{
int hour;
int min;
int sec;
int meridiem;
} my_time_t;
void processAnother(void)
{
char ans;
printf("Process another [y/n]");
// note the space at the start
// that means to discard all whitespace
// exit if ans different than 'y'
if (scanf(" %c", &ans) <= 0 || ans != 'y')
exit(0);
}
// don't prototype your fuctions with int if they return nothing
void result(my_time_t *time, int input)
{
// use variable with explicit name
char *meridiem;
int notation;
if(time->meridiem == 1)
{
meridiem = "AM";
}
else if (time->meridiem == 2)
{
meridiem = "PM";
}
// it's the same as old notation if you don't know the << operator search what bitshift is on the internet
// y = 6 << input <==> y = 6 * 2 ^ input
// so if input = 1 : y = 6 * 2 ^ 1 = 12
// if input = 2 : y = 6 * 2 ^ 2 = 24
notation = 6 << input;
printf("The %d-hr Notation is : %d:%d:%d %s\n", notation, time->hour, time->min, time->sec, meridiem);
return;
}
int are_time_correct(my_time_t *time, int input)
{
int check = 1;
// double parenthesis are not needed
// (6 << input) can be equal at 12 or 24 in function of input see above for more informations
if (time->hour > (6 << input) || time->hour < 0)
{
printf("\nError! Invalid Hour\n");
check = 0;
}
if (time->min >= 60 || time->min < 0)
{
printf("\nError! Invalid Minute\n");
check = 0;
}
if (time->sec >= 60 || time->sec < 0)
{
printf("\nError! Invalid Second\n");
check = 0;
}
// i don't think the meridiem can be below 0 so I replace (time->meridiem < 0) by (time->meridiem < 1)
if (time->meridiem > 2 || time->meridiem < 1)
{
printf("\nError! Invalid Meridiem\n");
check = 0;
}
return (check);
}
int convert24(my_time_t *time, int input)
{
if (are_time_correct(time, input) && time->hour == 12)
{
// if time->meridiem == 1 :
// time->hour = 12 * (1 - 1) = 0
// if time->medriem == 2 :
// time->hour = 12 * (2 - 1) = 12
time->hour = 12 * (time->meridiem - 1);
}
result(time, input);
// processAnother(); is not needed you already do it on the main loop
return (0);
}
int convert12(my_time_t *time, int input)
{
if (are_time_correct(time, input) && time->hour > 12)
{
time->hour -= 12;
}
result(time, input);
// processAnother(); is not needed you already do it on the main loop
return (0);
}
int menu(void)
{
int input;
my_time_t time;
// string concatenation
printf("[1] Convert to 24-hour notation\n"
"[2] Convert to 12-hour notation\n"
"[3] Quit\n");
if (scanf(" %d", &input) <= 0)
{
printf("\nWrong input\n");
input = 3;
}
switch(input)
{
case 1 :
{
printf("Enter hours (1-12):minute(1-59):seconds(1-59): ");
if (!scanf(" %d", &time.hour) <= 0 ||
!scanf(" %d", &time.min) <= 0 ||
!scanf(" %d", &time.sec) <= 0)
{
printf("\nWrong input\n");
return (1);
}
printf("[1] AM or [2] PM: ");
if (!scanf(" %d", &time.meridiem) <= 0)
{
printf("\nWrong input\n");
return (1);
}
return convert24(&time, input);
break;
}
case 2 :
{
printf("Enter hours(1-24):minute(1-59):seconds(1-59): ");
if (scanf(" %d", &time.hour) <= 0 ||
scanf(" %d", &time.min) <= 0 ||
scanf(" %d", &time.sec) <= 0)
{
printf("\nWrong input\n");
return (1);
}
printf("[1]AM or [2]PM: ");
if (scanf(" %d", &time.meridiem) <= 0)
{
printf("\nWrong input\n");
return (1);
}
return convert12(&time, input);
break;
}
default :
{
printf("Goodbye :)");
exit(0);
}
}
return (0);
}
// function without parameters are declared with void
int main(void)
{
// a while loop is simpler imo
while (1)
{
// if menu() return 1 it means the user enter a wrong input
// in that case no need to call processAnother()
if (!menu())
{
processAnother();
}
// DON'T USE SYSTEM NEVER EVER SEE HERE FOR MORE INFO https://stackoverflow.com/questions/19913446/why-should-the-system-function-be-avoided-in-c-and-c
// anyway some shell (such as mine) don't reconise `cls` and use clear instead
system("cls");
}
return (0);
}
you also didn't test if scanf returned something, they're some case where you program will segfault

Tic-Tac-Toe Game Function To Check For Winner

I've written the following code for a tic-tac-toe game on my own:
#include <stdio.h>
#include <math.h>
void instructions();
void printboard(char board[3][3]);
int wincheck(char board[3][3]);
int main(){
char tictac[3][3] = {{'-', '-', '-'}, {'-', '-', '-'}, {'-', '-', '-'}};
int player = 0;
int win = 0;
int player_choice = 0;
int row = 0;
int col = 0;
instructions();
for(int i=0; i<9 && win==0; i++){
printboard(tictac);
player = i%2 + 1;
do{
printf("\nPlayer #%d, enter your spot choice:\n", player);
scanf("%d", &player_choice);
if(player_choice == 1){
row = 0;
col = 0;
}
else if(player_choice == 2){
row = 0;
col = 1;
}
else if(player_choice == 3){
row = 0;
col = 2;
}
else if(player_choice == 4){
row = 1;
col = 0;
}
else if(player_choice == 5){
row = 1;
col = 1;
}
else if(player_choice == 6){
row = 1;
col = 2;
}
else if(player_choice == 7){
row = 2;
col = 0;
}
else if(player_choice == 8){
row = 2;
col = 1;
}
else if(player_choice == 9){
row = 2;
col = 2;
}
else{
printf("Not a valid choice, please choose again.");
}
}while(player_choice<0 || player_choice>9 || tictac[row][col]!='-');
if(player == 1){
tictac[row][col] = 'X';
}
else if(player == 2){
tictac[row][col] = 'O';
}
if(wincheck(tictac)!=0){
win = player;
}
}
printboard(tictac);
if(!win){
printf("\n\nTHE GAME IS A DRAW!\n");
}
else{
printf("\n\nCONGRATULAIONS PLAYER #%d, YOU WON!\n", win);
}
}
void instructions(){
printf("\n\t\t\t WELCOME TO TIC TAC TOE!\n");
printf("\nGame Rules:\n");
printf("\nThe program will ask the player to enter which spot they would like to place their X or O.\nPlease use spot numbers as shown below:\n\n");
printf("\t\t\t\t 1 | 2 | 3 \n");
printf("\t\t\t\t---+---+---\n");
printf("\t\t\t\t 4 | 5 | 6 \n");
printf("\t\t\t\t---+---+---\n");
printf("\t\t\t\t 7 | 8 | 9 \n");
printf("\n\t------------------------LET'S BEGIN!------------------------\n\n\n");
}
void printboard(char board[3][3]){
printf("\t\t\t\t %c | %c | %c \n", board[0][0], board[0][1], board[0][2]);
printf("\t\t\t\t---+---+---\n");
printf("\t\t\t\t %c | %c | %c \n", board[1][0], board[1][1], board[1][2]);
printf("\t\t\t\t---+---+---\n");
printf("\t\t\t\t %c | %c | %c \n", board[2][0], board[2][1], board[2][2]);
}
int wincheck(char board[3][3]){
if((board[0][0]==board[0][1] && board[0][0]==board[0][2]) || (board[1][0]==board[1][1] && board[1][0]==board[1][2]) || (board[2][0]==board[2][1] && board[2][0]==board[2][2])){
return 1;/*Checks to see if player has won across any of the rows.*/
}
else if((board[0][0]==board[1][0] && board[0][0]==board[2][0]) || (board[0][1]==board[1][1] && board[0][1]==board[2][1]) || (board[0][2]==board[1][2] && board[0][2]==board[2][2])){
return 1;/*Checks to see if player has won down any columns.*/
}
else if((board[0][0]==board[1][1] && board[0][0]==board[2][2]) || (board[0][2]==board[1][1] && board[0][2]==board[2][0])){
return 1;/*Checks to see if player has won in a diagonal.*/
}
else{
return 0;
}
}
I'm running into an issue when trying to play the game though. After the first player chooses a "play spot" it thinks they have won already. Because of this I believe the issue is most likely due to an error in the wincheck function but I can't quite figure out what exactly is causing the issue. I'm a beginner programmer, so I apologize if this is kind of a dumb question. I really appreciate any help you can offer!
The problem is indeed with your wincheck function. It rightly checks that the three candidate cells are equal but does not check that those cells have been populated. That means the game will be detected as won even before a move is made (since all cells are set to -, a simple equality check will pass).
It's therefore not enough to do just the equality check, you also have to ensure that at least one of those cells has been set to a real player.
You can also make your code a bit more readable with a little refactoring, something like:
// Returns the actual winner, or '-' if none. Needs x/y start cell
// and x/y deltas (direction, basically).
int checkOneWinPossibility(char board[3][3], int x, int y, int xd, int yd) {
// Check all no-winner scenarios, return winner only if they all fail.
if (board[x][y] == '-') return '-';
if (board[x][y] != board[x+xd][y+yd]) return '-';
if (board[x][y] != board[x+xd*2][y+yd*2]) return '-';
return board[x][y];
}
int checkAllWinPossibilities(char board[3][3]){
int winner;
// Horizontals.
if ((winner = checkOneWinner(board, 0, 0, 0, 1)) != '-') return winner;
if ((winner = checkOneWinner(board, 1, 0, 0, 1)) != '-') return winner;
if ((winner = checkOneWinner(board, 2, 0, 0, 1)) != '-') return winner;
// Verticals.
if ((winner = checkOneWinner(board, 0, 0, 1, 0)) != '-') return winner;
if ((winner = checkOneWinner(board, 0, 1, 1, 0)) != '-') return winner;
if ((winner = checkOneWinner(board, 0, 2, 1, 0)) != '-') return winner;
// Diagonals.
if ((winner = checkOneWinner(board, 0, 0, 1, 1)) != '-') return winner;
if ((winner = checkOneWinner(board, 2, 0, -1, 1)) != '-') return winner;
return '-';
}
That last diagonal check could be combined with the return statement just by doing:
return checkOneWinner(board, 2, 0, -1, 1);
but I prefer (being slightly OCD) to leave it as is for consistency :-)
They also both return the actual winner rather than just an indication that there is a winner. You may not need that information since it will obviously be the last player that moved, but there's no probably no substantial harm in returning the extra information.

Resources