Countdown timer in C without freezing user input - c

I'm a newbie in C. I'm on the verge of finishing a program. Can anybody teach me how to make a countdown timer while being able to input something? I'm currently using sleep(), and as I've heard, it's bad for threading, and freezes input. Is that right?
Here's the function:
void nowPlaying(SONG * h, SONG * t, int * randPrev, int shuffleCon)
{
SONG * ptr;
ptr = h->next;
int random, randCount, mincount = 0, choice = 4, tot = 0, tot2 = 0;
if(h->next == t) {
printf("No songs to be played. Add some!\n");
}
else if(h->next != t) {
while(ptr->next != t) {
tot2 = tot = ((ptr->cdown.minutes*60) + ptr->cdown.secs);
do {
printf("------------------------YouTunes------------------------\n");
printf("========================================================\n");
printf("TITLE : %s \n", ptr->title);
printf("ARTIST: %s \n", ptr->artist);
printf("ALBUM : %s \n", ptr->album);
switch(ptr->genre) {
case 1:
printf("GENRE : POP \n");
break;
case 2:
printf("GENRE : OPM \n");
break;
case 3:
printf("GENRE : ROCK \n");
break;
case 4:
printf("GENRE : R&B \n");
break;
case 5:
printf("GENRE : ACOUSTIC \n");
break;
case 6:
printf("GENRE : CLASSICAL \n");
break;
}
while(tot2 >= 60) {
tot2 = tot2 - 60;
mincount++;
//if(time_left % 60 == 0) mincount++;
}
printf("TIME: ");
if(mincount < 10)
printf("0%d", mincount);
else
printf("%d", mincount);
printf(":");
if(tot2 < 10)
printf("0%d", tot2);
else if(tot2 == 60)
printf("00");
else
printf("%d", tot2);
printf("\n========================================================\n");
printf("[1] Prev [0]Exit [2] Next\n");
printf("Choice: ");
//scanf("%d", &choice);
//timeout(500);
tot--;
tot2 = tot;
mincount = 0;
sleep(1);
system("clear");
if(shuffleCon == 0) {
if(choice == 1) {
if(ptr->prev == h) {
//do nothing
}
else if(ptr->prev != h) {
ptr = ptr->prev;
}
}
else if(choice == 2) {
if(ptr->next == t) {
//do nothing
}
else if(ptr->next != t) {
ptr = ptr->next;
}
}
}
else if(shuffleCon == 1) {
if(choice == 1) {
random = shuffle(h, t, randPrev);
randCount = 0;
ptr = h->next;
while(randCount != random) {
ptr = ptr->next;
randCount++;
}
}
else if(choice == 2) {
random = shuffle(h, t, randPrev);
randCount = 0;
ptr = h->next;
while(randCount != random) {
ptr = ptr->next;
randCount++;
}
if(ptr == t) {
ptr = ptr->prev;
ptr = ptr->prev;
}
}
}
} while(tot != -1);
if(shuffleCon == 0)
ptr = ptr->next;
else if(shuffleCon == 1) {
random = shuffle(h, t, randPrev);
randCount = 0;
ptr = h->next;
while(randCount != random) {
ptr = ptr->next;
randCount++;
}
}
}
}
}

Broadly speaking, one of these:
Use SIGALRM (see the alarm man page), and rely on the signal to interrupt the system call expecting user input.
(Better, and certainly a more valuable programming exercise), write an event loop with select or poll and set the timeout to be the time remaining until the timeout.
For the sort of application you are talking about, (2) would be a better choice.

Related

Can't get my C program to print the output

When I go to print the output of the program everything shows up as zero. I think the variable aren't storing themselves, but I'm not totally sure. When I go to look over everything, it looks right but clearly isn't. Any help would be really appreciated. Sorry if the formatting seems a little off, Stack Overflow wouldn't accept it otherwise.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int digit(char term[])
{
int i = 0;
int val = 0;
while (term[i] != '\0')
{
val = val * 10 + term[i] - '0';
}
i++;
return val;
}
void error()
{
printf("Error: Sales figures must be numbers.\n");
printf("Please try again.\n");
}
bool isnumber(char term[])
{
int i = 0;
while (term[i])
{
if( isdigit(term[i]) == 0)
{
return false;
i++;
}
}
return true;
}
int main()
{
int sales[3][2], costs[3] = {3, 4, 1}, weekends[2] = {0, 0};
int i, j, val;
char term[100];
while (1)
{
printf("Number of Bagel sales on Saturday: ");
scanf("%s", term);
if( isnumber(term) == false)
{
error();
}
else
{
sales[0][0] = digit(term);
break;
}
}
while (1)
{
printf("Number of Flatbread sales on Saturday: ");
scanf("%s", term);
if( isnumber(term) == false)
{
error();
}
else
{
sales[1][0] = digit(term);
break;
}
}
while (1)
{
printf("Number of Muffin sales on Saturday: ");
scanf("%s", term);
if (isnumber(term) == false)
{
error();
}
else
{
sales[2][0] = digit(term);
break;
}
}
while (1)
{
printf("Number of Bagel sales on Sunday: ");
scanf("%s", term);
if( isnumber(term) == false)
{
error();
}
else
{
sales[0][1] = digit(term);
break;
}
}
while (1)
{
printf("Number of Flatbread sales on Sunday: ");
scanf("%s", term);
if( isnumber(term) == false)
{
error();
}
else
{
sales[1][1] = digit(term);
break;
}
}
while (1)
{
printf("Number of Muffin sales on Sunday: ");
scanf("%s", term);
if( isnumber(term) == false)
{
error();
}
else
{
sales[2][1] = digit(term);
break;
}
}
for (i = 0; i < 2, i++;)
{
for (j = 0; j < 3, j++;)
{
weekends[i] += costs[j] * sales[i][j];
}
}
printf("\n");
for (i = 0; i < 3, i++;)
{
printf("%d", costs[i]);
}
printf(".");
for (i = 0; i < 3, i++;)
{
for (j = 0; j < 2, j++;)
{
printf("%d", sales[i][j]);
}
if (i == 0)
{
printf(" = ");
printf("%d %d", weekends[0], weekends[1]);
}
printf("\n ");
}
printf("\nTotal sales on Saturday: $%d", weekends[0]);
printf("\nTotal sales on Sunday: $%d", weekends[1]);
printf("\nTotal sales over the weekend: $%d", weekends[0] + weekends[1]);
return 0;
}
You are not incrementing i in the loop. Your code for digit is:
int digit(char term[])
{
int i = 0;
int val = 0;
while (term[i] != '\0')
{
val = val * 10 + term[i] - '0';
}
i++; /* ---- this is outside the loop !! */
return val;
}
But it ought to look like:
int
digit(const char *term)
{
int val = 0;
while( *term != '\0' ){
val = val * 10 + *term - '0';
term += 1;
}
return val;
}

How to read json packets for particular keyword in C?

This my json packet and I want to read "14.469121":
{"jsonrpc": "2.0", "method": "notifySpeed", "params": {"speed": "14.469121"}}
I tried some online solutions and implemented some logic.
ptr = strtok(parse_recData,", ");
while(ptr != NULL)
{
countTillMethod--;
if(countTillMethod == 0)
{
if(strcmp(ptr,"\"notifySpeed\"")==0)
{
if(!(strcmp(ptr,"\"Speed\"" )))
Speed = strtok(NULL,", ");
SpeedValue = atoi (Speed);
if (SpeedValue > PERMISSIBLE_LIMIT)
touchControl (DISABLE);
else
touchControl (ENABLE);
}
}
}
I want to read speed data.
Thank you everyone help, finally i implement successfully.
else if(strcmp(ptr,"\"notifySpeed\"")==0)
{
syslog(LOG_INFO,"Received Speed\n");
ptr1 = strstr(parse_recData_backup, "\"params\"");
ptr1 += strlen("params");
ptr1 = strstr(parse_recData_backup, "\"speed\": ");
ptr1 += strlen("\"speed\": ") + 1;
/* get the exect value */
for(i=0; ptr[i]!='\0'; ++i)
{
while (!((ptr1[i]>='0'&&ptr1[i]<='9') || (ptr1[i] == '.') || (ptr1[i] == '\0')))
{
for(j=i;ptr1[j]!='\0';++j)
{
ptr1[j]=ptr1[j+1];
}
ptr1[j]='\0';
}
}
syslog(LOG_INFO," %s \r\n", ptr1);
/* Converts the string to integer */
Speed = atoi(ptr1);
syslog(LOG_INFO," speed is %d \r\n", Speed);
/* Compare the speed with permissiable limit */
if (Speed > PERMISSIBLE_LIMIT)
touchControl (DISABLE);
else
touchControl (ENABLE);
}
char parse_recData[215] = {"jsonrpc": "2.0", "method": "notifySpeed", "params": {"speed": "14.469121"}};
char parse_recData_backup[215];
char *ptr1 = NULL;
int Speed = 0;
strcpy(parse_recData_backup, parse_recData);
ptr = strtok(parse_recData,", ");
while(ptr != NULL)
{
countTillMethod--;
if(countTillMethod == 0)
{
if(strcmp(ptr,"\"notifySpeed\"")==0)
{
syslog(LOG_INFO,"Received Speed\n");
ptr1 = strstr(parse_recData_backup, "\"speed\": ");
ptr1 += strlen("\"speed\": ") + 1;
/* Converts the string to integer */
Speed = atoi(ptr1);
syslog(LOG_INFO," speed is %d \r\n", Speed);
/* Compare the speed with permissiable limit */
if (Speed > PERMISSIBLE_LIMIT)
touchControl (DISABLE);
else
touchControl (ENABLE);
}
}
ptr = strtok(NULL, ",");
}

C programming: Reverse ordered list

I'm trying to "scroll" through a list of names I got the scroll down part right but I can't figure out how to go backwards (scroll up). I The error lies in the i + j -1, but I just cant get the right output without a segmentation fault. This is because I'm trying to access a negative number I'm assuming.
int i,list,j = 1;
char answer [5];
do {
if (strcmp(answer, "+") == 0) {
printf("Number of Contacts = %d\n", count);
for(i=1;i<6;i++) {
if ((i + j) - 1 == count) {
printf("end of list\n");
break;
} else {
list = i + j;
if(strcmp(contactData[(i+j)-1].company_name," ") == 0) {
printf("%d.\t%s %s\n", list, contactData[(i+j)-1].first_name, contactData[(i+j)-1].last_name);
} else {
printf("%d.\t%s\n", list, contactData[(i+j)-1].company_name);
}
}
}
}
if (strcmp(answer, "-") == 0) {
printf("Number of Contacts = %d\n", count);
for(i=1;i<6;i++) {
if ((i + j - 1) < 0) {
printf("end of list\n");
break;
} else {
list = j - i;
if(strcmp(contactData[(j-i)-1].company_name," ") == 0) {
printf("%d.\t%s %s\n", list, contactData[(j-i)-1].first_name, contactData[(j-i)-1].last_name);
} else {
printf("%d.\t%s\n", list, contactData[(j-i)-1].company_name);
}
}
}
}
printf("Action(+,-,#,A,X):");
scanf("%s", answer);
getchar();
j++;
} while (1)
This is my output:
Number of Contacts = 14
1. Chiraq
2. Cobra
3. Andre D'Souza
4. Gucci
5. Jordan
Action(+,-,#,A,X):+
Number of Contacts = 14
2. Cobra
3. Andre D'Souza
4. Gucci
5. Jordan
6. Migos
Action(+,-,#,A,X):+
Number of Contacts = 14
3. Andre D'Souza
4. Gucci
5. Jordan
6. Migos
7. North Face
If your contactData array starts at [0] and ends at [count-1] this example could work for you.
int i,list,j = 0;
char answer [5];
do {
printf("Number of Contacts = %d\n", count);
for(i=0;i<6;i++) {
list = i+j;
if (list >= count) {
printf("end of list\n");
break;
}
if(strcmp(contactData[list].company_name," ") == 0) {
printf("%d.\t%s %s\n", list+1, contactData[(list].first_name, contactData[list].last_name);
} else {
printf("%d.\t%s\n", list+1, contactData[(list].company_name);
}
}
printf("Action(+,-,#,A,X):");
scanf("%s", answer);
if(strcmp(answer, "+") == 0) {
if((j+1)<count) j++;
}
else if(strcmp(answer, "-") == 0) {
if(j>0) j--;
}
} while (1);

Loop incomplete

I just started learning coding for about 2 months because of the course im taking.
My code works (kinda) but after the 1st loop it wont show the 1st line of the main function("You have been given 20 pokeballs, embrak on you quest on becoming a Pokeman Master!!!:), and i dont know why!
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int pokeball = 20;
int rand_num;
int PokemonCaught[5] = { 0, 0, 0 ,0, 0 };
int poke_captured = 0;
int rungame = 1;
int stopgame = 1;
int total;
int randomnum();
int encounter_rate();
int pokemon_met();
void BallThrow();
void CaughtPokemon();
void checkball();
void PokeSummary();
char exitno();
int clear();
int main()
{
printf("You have been given 20 pokeballs, embrak on you quest on becoming a Pokeman Master!!!\n");
getchar();
do
{
checkball();
encounter_rate();
pokemon_met();
} while (stopgame == 0);
PokeSummary();
return 0;
}
int randomnum()
{
srand(time(NULL));
}
int encounter_rate()
{
randomnum();
rand_num = rand() % 100;
}
int pokemon_met()
{
if (rand_num <= 30)
{
printf("A wild Margikarp appeared!.\n");
printf("Press ENTER to throw a pokeball!. \n");
getchar();
rungame = 1;
BallThrow();
}
else if (rand_num <= 50)
{
printf("A wild Charmander appeared!.\n");
printf("Press ENTER to throw a pokeball!. \n");
getchar();
rungame = 1;
BallThrow();
}
else if (rand_num <= 70)
{
printf("A wild Jigglypuff appeared!.\n");
printf("Press ENTER to throw a pokeball!. \n");
getchar();
rungame = 1;
BallThrow();
}
else if (rand_num <= 85)
{
printf("A wild Pikachu appeared!.\n");
printf("Press ENTER to throw a pokeball!. \n");
getchar();
rungame = 1;
BallThrow();
}
else
{
printf("A wild Dragonite appeared!.\n");
printf("Press ENTER to throw a pokeball!. \n");
getchar();
rungame = 1;
BallThrow();
}
}
void checkball()
{
if (pokeball > 0)
{
stopgame = 0;
}
else
{
stopgame = 1;
}
}
void BallThrow()
{
randomnum();
int BallChance;
int PokeRun;
BallChance = rand() % 2;
pokeball = pokeball - 1;
if (BallChance == 1)
{
printf("Gotcha!\n");
printf("Number of Pokeball left: %d\n", pokeball);
printf("Press ENTER to continue your journey!\n\n");
poke_captured = poke_captured + 1;
CaughtPokemon();
getchar();
if (pokeball == 0)
{
printf("Your pokeball has used up!\n");
printf("Press ENTER to check the summary of your journey\n");
getchar();
PokeSummary();
}
}
else if (BallChance == 0)
{
PokeRun = rand() % 2;
printf("The pokemon broke free!!!\n");
if (PokeRun == 0)
{
if (pokeball == 0)
{
printf("Your pokeball has used up!\n");
printf("Press ENTER to check the summary of your journey\n");
getchar();
PokeSummary();
}
else
{
printf("Number of Pokeball left: %d\n", pokeball);
printf("Press ENTER to throw pokeball!\n\n");
getchar();
BallThrow();
}
}
else if (PokeRun == 1)
{
printf("Oh no! The pokemon ran away!\n");
printf("Number of Pokeball left: %d\n", pokeball);
printf("Press ENTER to continue your journey!\n\n");
getchar();
if (pokeball == 0)
{
printf("Your pokeball has used up!\n");
printf("Press ENTER to check the summary of your journey\n");
getchar();
PokeSummary();
}
}
}
}
void CaughtPokemon()
{
if (rand_num <= 30)
{
PokemonCaught[0] = PokemonCaught[0] + 1;
}
else if (rand_num <= 50)
{
PokemonCaught[1] = PokemonCaught[1] + 1;
}
else if (rand_num <= 70)
{
PokemonCaught[2] = PokemonCaught[2] + 1;
}
else if (rand_num <= 85)
{
PokemonCaught[3] = PokemonCaught[3] + 1;
}
else if (rand_num <= 95)
{
PokemonCaught[4] = PokemonCaught[4] + 1;
}
}
void PokeSummary()
{
int point0, point1, point2, point3, point4, total;
point0 = (PokemonCaught[0]) * 10;
point1 = (PokemonCaught[1]) * 30;
point2 = (PokemonCaught[2]) * 30;
point3 = (PokemonCaught[3]) * 50;
point4 = (PokemonCaught[4]) * 70;
total = point0 + point1 + point2 + point3 + point4;
printf("You have successfully caught %d Pokemon!\n\n", poke_captured);
printf("You have caught:\n");
printf("Margikarp = %d (%dpoints)\n", PokemonCaught[0], point0);
printf("Charmander = %d (%dpoints)\n", PokemonCaught[1], point1);
printf("Jigglypuff = %d (%dpoints)\n", PokemonCaught[2], point2);
printf("Pikachu = %d (%dpoints)\n", PokemonCaught[3], point3);
printf("Dragonite = %d (%dpoints)\n", PokemonCaught[4], point4);
printf("\nTotal points = %d\n", total);
exitno();
}
char exitno()
{
char stay;
printf("Press 'y' to continue, press any other key to quit.");
scanf(" %c", &stay);
if (stay == 'y' || stay == 'Y')
{
clear();
return (main);
}
else
{
printf("Thank you for playing!!");
exit(0);
}
}
int clear()
{
total = total * 0;
poke_captured = poke_captured * 0;
PokemonCaught[0] = PokemonCaught[0] * 0;
PokemonCaught[1] = PokemonCaught[1] * 0;
PokemonCaught[2] = PokemonCaught[2] * 0;
PokemonCaught[3] = PokemonCaught[3] * 0;
PokemonCaught[4] = PokemonCaught[4] * 0;
pokeball = pokeball + 20;
}
I appreciate any help and i know my codes are far from being decent (sigh)
. Thanks
You have made an error when calling main in char exitno() function:
char exitno()
{
char stay;
printf("Press 'y' to continue, press any other key to quit.");
scanf(" %c", &stay);
if (stay == 'y' || stay == 'Y')
{
clear();
return ((char)main()); // main it should be called using parenthesis
}
else
{
printf("Thank you for playing!!");
exit(0);
}
}
That is not inside of your do-while loop.
If you want it to execute every time, then just move it down into the the loop. Otherwise, your program will move past in the first few milliseconds of operation. Alternatively, modify it (likely, put it within a new function) to print out some information that might change during execution of your program--say, the current number of pokeballs remaining.

Line in text file is evaluated multiple times?

I need to convert infix to postfix and evaluate postfix expression. When reading from a file, I should be able to evaluate multiple expressions at once. But when I run it and it encounters an expression that is not well-formed in the sense that there are more closed parentheses than open ones, it evaluates that expression 2 or 3 times.
Code:
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define MAX 1000
typedef struct stack
{
int data[MAX];
int top;
} stack;
int priority(char);
void init(stack*);
int empty(stack*);
int full(stack*);
char pop(stack*);
void push(stack*, char);
char top(stack*);
void add(char*, char, int);
void keyboard();
void read_file();
int change(char);
void pushYO(double);
double popYO();
stack s;
char x;
int i, token, topYO = -1;
double result[MAX];
char filepath[MAX];
int main()
{
char choice;
init(&s);
system("CLS");
printf("[1] Keyboard \n[2] Read from text file \n[3] Exit \n");
scanf("%c", &choice);
if(choice != '1' && choice != '2' && choice != '3')
{
main();
}
else if(choice == '1')
{
keyboard();
}
else if(choice == '2')
{
read_file();
}
else if(choice == '3')
{
printf("\nThank you for using Kei Shirabe's \ninfix to postfix converter and evaluator! :)\n");
exit(0);
}
}
void keyboard() //the keyboard input version. this works fine
{
//code here
}
void read_file()
{
int z, count, form, paren;
double one, two, three = 1;
char infx[MAX];
char pofx[MAX];
char choice;
FILE *text = fopen("text.txt", "a");
printf("Enter path of file:");
scanf("%s",&filepath);
FILE *textYO = fopen(filepath, "r");
if((textYO) == NULL)
{
printf("\nError! Unable to open %s\n\n", filepath);
}
else
{
while((fgets(infx, MAX, textYO))!= NULL)
{
form = -1, paren = 0, count = 0, z = 0;
infx[
strlen(infx)-1] = '\0';
for (i=0; i<strlen(infx); i++)
{
if((token = infx[i]) != '\n')
{
if(isalnum(token))
{
form++;
}
else
{
if(token == '(')
{
paren++;
}
else if(token == ')')
{
paren--;
}
else
{
form--;
}
}
if (paren < 0)
{
printf("%s", infx);
fprintf(text, "%s", infx);
printf("\n\nError! Not well formed :( \n-----------------\n");
fprintf(text, "\n\nError! Not well formed :( \n-----------------\n");
}
else
if(isalnum(token))
{
add(pofx, token, count);
count++;
}
else
if(token == '(')
{
push(&s, '(');
}
else
{
if(token == ')')
while((x = pop(&s)) != '(')
{
add(pofx, x, count);
count++;
}
else
if(token == '^')
{
push(&s, token);
}
else
{
while(priority(token) <= priority(top(&s)) && !empty(&s))
{
x = pop(&s);
add(pofx, x, count);
count++;
}
push(&s, token);
}
}
}
else
{
while(!empty(&s))
{
x = pop(&s);
add(pofx, x, count);
count++;
}
}
}
if(form != 0 || paren != 0)
{
printf("%s", infx);
fprintf(text, "%s", infx);
printf("\n\nError! Not well formed :( \n-----------------\n");
fprintf(text, "\n\nError! Not well formed :( \n-----------------\n");
}
else
{
form = -1, paren = 0;
printf("%s", infx);
fprintf(text, "%s", infx);
printf("\n\nPostfix: %s \n\n", pofx);
fprintf(text, "\n\nPostfix: %s\n\n", pofx);
while((token = pofx[z++]) != '\0')
{
three = 1;
if(!isdigit(token) && !isalpha(token))
{
two = popYO();
one = popYO();
switch(token)
{
case '+':
pushYO(one+two); break;
case '-':
pushYO(one-two); break;
case '*':
pushYO(one*two); break;
case '/':
pushYO(one/two); break;
case '^':
if (two > 0)
{
for(i=0;i<two;i++)
{
three = three * one;
}
pushYO(three);
three = 1; break;
}
else
{
for(i=0;i<(two-(2*two));i++)
{
three = three * one;
}
pushYO((1/three));
three = 1; break;
}
}
}
else if(isalpha(token))
{
if(isupper(token))
{
pushYO(token - '#');
}
if(islower(token))
{
pushYO(token - change(token));
}
}
else
{
pushYO(token - '0');
}
}
printf("Result: %lf\n-----------------\n", result[topYO]);
fprintf(text, "Result: %lf\n-----------------\n", result[topYO]);
}
}
}
fclose(text);
fclose(textYO);
printf("\nRun again? \n[1] Yes \n[any other key] No\n");
scanf("%c", &choice);
scanf("%c", &choice);
if(choice == '1')
{
main();
}
else
{
printf("\nThank you for using Kei Shirabe's \ninfix to postfix converter and evaluator! :)\n");
exit(0);
}
}
//other functions down here, not important
Sample text file (and yes there is an extra space at the end):
(1+2))
(1+2*3)
For this text file, the expression (1+2)) is evaluated three times, each result being "Not well formed". The last expression works as expected.
Any help please?

Resources