clock using fflush is not clearing screen - c

I am trying to make a clock in C, but the screen is not properly clearing, it just keeps printing to a new line. How am I improperly using fflush?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
while (1) {
time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
printf ("%s", asctime (timeinfo));
fflush(stdout);
}
return 0;
}

This strips out the newline from the asctime string and then uses a return to push the cursor back to the start of line
#include <string.h>
int main()
{
while (1) {
time_t rawtime;
char st[30];
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
sprintf (st,"%s", asctime (timeinfo));
*(index(st,'\n'))='\0';
printf("\r%s",st);
flush(stdout);
sleep(1);
}
return 0;
}

This one has the advantage that it will work from the current location on the screen, no matter what that is. I added a label to print "The time is: " in order to show this. It does this by back spacing from the end of the time string rather than going to an absolute screen position or column. Caveat: The hack to get sleep() under Visual C has not been tried.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#ifdef _MSC_VER
#include <windows.h>
#define sleep(T) Sleep((T) * 1000)
#else
#include <unistd.h>
#endif
int main(void)
{
char buf[42];
time_t the_time[1];
int i, len;
printf("The time is: ");
for (;;) {
time(the_time);
len = strlen(strcpy(buf, asctime(localtime(the_time)))) - 1;
printf("%.*s", len, buf);
for (i = 0; i < len; i++) putchar('\b');
fflush(stdout);
sleep(1);
}
return 0;
}

This will do it... (uses an evil windows call SetConsoleCursorPosition(), but does the trick)
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void gotoxy(int x, int y);
int main()
{
while (1) {
time_t rawtime;
struct tm * timeinfo;
gotoxy(0,0);//set to the upper left hand corner
time ( &rawtime );
timeinfo = localtime ( &rawtime );
printf ("%s", asctime (timeinfo));
fflush(stdout);
}
return 0;
}
void gotoxy(int x, int y)
{
COORD pos = {x, y};
HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(output, pos);
}
Try this for POSIX:
#!/usr/bin/tcc -run
#include <stdio.h>
#include <termios.h>
int main ()
{
struct termios ts0, ts1;
char cls [FILENAME_MAX];
FILE *f;
f = popen ("tput clear", "r");
fgets (cls, FILENAME_MAX, f);
pclose (f);
tcgetattr (0, &ts0);
ts1 = ts0;
ts1.c_lflag &= ~ECHO;
ts1.c_lflag &= ~ICANON;
tcsetattr (0, TCSAFLUSH, &ts1);
fputs (cls, stdout);
while (1) putchar (getchar ());
tcsetattr (0, TCSAFLUSH, &ts0);
return 0;
}

Related

Implement overlay in terminal

I want to create an overlay in terminal
This Q&D shows the time in right/bottom
#include <stdio.h>
#include <stdlib.h>
#include <termcap.h>
#include <termios.h>
#include <error.h>
#include <unistd.h>
#include <time.h>
static char termbuf[2048];
int main()
{
char *termtype = getenv("TERM");
time_t timer;
char buffer[26];
struct tm* tm_info;
if (tgetent(termbuf, termtype) < 0) {
error(EXIT_FAILURE, 0, "Could not access the termcap data base.\n");
return 1;
}
int lines = tgetnum("li");
int columns = tgetnum("co");
int pos=1;
while (1) {
time(&timer);
tm_info = localtime(&timer);
strftime(buffer, 26, "%Y-%m-%d %H:%M:%S", tm_info);
printf("\033[s");
fflush(stdout);
printf("\033[%d;%dH%s\n", lines - 2, columns - 20, buffer);
printf("\033[u");
sleep(1);
}
return 0;
}
it is compiled with:
$ gcc time-overlay.c -ltermcap -o time-overlay
And to use it:
$ ./time-overlay &
It will show:
2017-04-29 12:29:15
And keep updating time.
To stop:
$ fg
Ctrl+C
But, is there a better way to do that with some library that abstracts low level calls (like save restore cursor position or print in some line/col)
I want to keep existing terminal output (so curses with initscr() will not work)
This is how you would use termcap (or anything provides a termcap interface, e.g., ncurses):
#include <stdio.h>
#include <stdlib.h>
#include <termcap.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#define MAXTERM 2048
#define EndOf(s) (s) + strlen(s)
int
main(void)
{
char termbuf[MAXTERM];
char workbuf[MAXTERM];
char *working = workbuf;
int lines, columns;
char *save_cursor, *move_cursor, *restore_cursor;
if (tgetent(termbuf, getenv("TERM")) < 0) {
fprintf(stderr, "Could not access the termcap database.\n");
return EXIT_FAILURE;
}
lines = tgetnum("li");
columns = tgetnum("co");
save_cursor = tgetstr("sc", &working);
move_cursor = tgetstr("cm", &working);
restore_cursor = tgetstr("rc", &working);
while (1) {
time_t timer;
char buffer[1024];
struct tm *tm_info;
time(&timer);
tm_info = localtime(&timer);
strcpy(buffer, save_cursor);
sprintf(EndOf(buffer), tgoto(move_cursor, columns - 20, lines - 2));
strftime(EndOf(buffer), 26, "%Y-%m-%d %H:%M:%S", tm_info);
strcat(buffer, restore_cursor);
write(fileno(stderr), buffer, strlen(buffer));
sleep(1);
}
return EXIT_SUCCESS;
}
It could still be improved since the various strings returned from tgetstr are not guaranteed to be provided by all terminal descriptions, and of course, termcap applications always have buffer-overflow issues to work around.

Pass string as argument into C program in terminal

So i'm working on linux and my question is how make a program accept arguments in execution like this one:
./program am i
Also both functions work the same way at the moment, because i'm struggling with getting only this line:
(expected result of show_info_who_am_i)
Kamil pts/0 2015-11-12 10:14 (:0)
instead of both of them:
(result of show_info_who)
Kamil tty2 2015-11-12 10:13 (:0)
Kamil pts/0 2015-11-12 10:14 (:0)
#include <stdio.h>
#include <utmp.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#define SHOWHOST /* include remote machine on output */
show_info_who( struct utmp *utbufp )
{
if(utbufp->ut_type > 4){
time_t czas = utbufp->ut_time;
char buf[80];
struct tm* timeinfo = localtime(&czas);
printf("%-8.8s", utbufp->ut_name); /* the logname */
printf(" "); /* a space */
printf("%-8.8s", utbufp->ut_line); /* the tty */
printf(" "); /* a space */
strftime(buf, 80, "%F %R" , timeinfo);
printf("%s", buf);
printf(" "); /* a space */
#ifdef SHOWHOST
printf("(%s)", utbufp->ut_host); /* the host */
#endif
printf("\n"); /* newline */
}
}
show_info_who_am_i( struct utmp *utbufp )
{
if(utbufp->ut_type > 4){
time_t czas = utbufp->ut_time;
char buf[80];
struct tm* timeinfo = localtime(&czas);
printf("%-8.8s", utbufp->ut_name); /* the logname */
printf(" "); /* a space */
printf("%-8.8s", utbufp->ut_line); /* the tty */
printf(" "); /* a space */
strftime(buf, 80, "%F %R" , timeinfo);
printf("%s", buf);
printf(" "); /* a space */
#ifdef SHOWHOST
printf("(%s)", utbufp->ut_host); /* the host */
#endif
printf("\n"); /* newline */
}
}
int main(int argc, char *argv[])
{
struct utmp current_record; /* read info into here */
int utmpfd; /* read from this descriptor */
int reclen = sizeof(current_record);
if ( (utmpfd = open(UTMP_FILE, O_RDONLY)) == -1 ){
perror( UTMP_FILE ); /* UTMP_FILE is in utmp.h */
exit(1);
}
//char am[22] = "am"; /* test */
//char i[22] = "i"; /* test */
//printf("%s,%s\n\n", am,i); /* test */
//printf("%s", argv[1]);
if(argv[1]== "am"){
if(argv[2]== "i"){
while ( read(utmpfd, &current_record, reclen) == reclen )
show_info_who_am_i(&current_record);
}
}
else{
while ( read(utmpfd, &current_record, reclen) == reclen )
show_info_who(&current_record);
}
//printf("%s,%s", argv[1], argv[2]); /* test */
close(utmpfd);
return 0; /* went ok */
}

how to get minute of the system time from C program

how to get minute of the system time from C program? can I use gettimeoftheday?? If anyone has C program which can do this please share, I'm a newbie.Thanks
some sample code
#include <sys/time.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char buffer[30];
struct timeval tv;
time_t curtime;
gettimeofday(&tv, NULL);
curtime=tv.tv_sec;
strftime(buffer,30,"%m-%d-%Y %T.",localtime(&curtime));
printf("%s%ld\n",buffer,tv.tv_usec);
return 0;
}
You can use strftime to get only the minutes part :
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char buffer[0x100];
time_t curtime;
// Don't forget to check the return value !
curtime = time(NULL);
if (curtime == -1)
{
perror("time()");
return 1;
}
strftime(buffer,0x100,"%M",localtime(&curtime));
printf("minutes: %s\n", buffer);
return 0;
}
No need to use gettimeofday here, use it only if you want a precision better than seconds.
#include <stdio.h>
#include <time.h>
int main()
{
time_t curtime;
char buffer[30];
struct tm* tm_info;
time(&curtime);
tm_info = localtime(&curtime);
strftime(buffer, 30, "%Y-%m-%d %H:%M:%S", tm_info);
puts(buffer);
return 0;
}
%Y:- will print year
%m:- will print Month
%d:- will print day
%H:- will print Hour
%M:- will print Minute
%S:- will print Second

Need help applying timer in C in Linux

I want to create a timer in our C program so that it can print the variable after every 1 second.
Can anybody help me in doing this?
Don't use busy waiting, because you've got 100% CPU utilization.
You must use system function which turns process into sleeping mode for example select():
#include <stdio.h>
#include <sys/select.h>
void your_callback()
{
printf("%s\n", __FUNCTION__);
}
int main()
{
struct timeval t;
while (1) {
t.tv_sec = 1;
t.tv_usec = 0;
select(0, NULL, NULL, NULL, &t);
your_callback();
}
return 0;
}
If all you are interested in doing is printing the value of a variable at a one second interval, using time(2) or clock(3) as suggested in the other answers might suffice. In general, I would not recommend these busy-waiting techniques.
If your program is more complex, I suggest you investigate using the alarm(2) or settimer(2) function to asynchronously deliver a signal to your application at a one second interval.
The following example uses select(2) to block indefinitely in order to minimize CPU usage associated with busy-waiting techniques. The blocking select() call is interrupted and returns when a signal is caught. In the case of the SIGALRM signal, the print_variable flag is set and the value of variable is printed.
Example 1: using alarm()
#include <signal.h>
#include <stdio.h>
#include <sys/select.h>
#include <unistd.h>
volatile unsigned int variable = 0;
volatile unsigned int print_variable = 0;
void alarm_handler(int signum)
{
variable++;
print_variable = 1;
alarm(1);
}
int main()
{
signal(SIGALRM, alarm_handler);
alarm(1);
for (;;)
{
select(0, NULL, NULL, NULL, NULL);
if (print_variable)
{
printf("Variable = %u\n", variable);
}
}
}
Note: Error checking was omitted from the above code for simplicity.
A printf() function could have been called inside the SIGALRM handler, but calling non-reentrant functions in a signal handler is generally discouraged.
A timeout of one second can also be passed to select(), but if it were interrupted by any signal, additional logic is necessary to ensure that the remainder of the one second timeout is honored. Fortunately on Linux, select() modifies the timeout value to reflect the amount of time not slept. This allows interruption cases to be detected followed by subsequent call(s) select() to complete the timeout.
Example 2: using select()
#include <errno.h>
#include <stdio.h>
#include <sys/select.h>
volatile unsigned int variable = 0;
int main()
{
struct timeval tv;
int val;
for (;;)
{
tv.tv_sec = 1;
tv.tv_usec = 0;
do
{
val = select(0, NULL, NULL, NULL, &tv);
} while (val != 0 && errno == EINTR);
printf("Variable = %u\n", ++variable);
}
}
If you want only second precision. Use time(0) which returns current time if time.h is included.
update:
Adding simple example which prints 10 in every second during 20 seconds:
#include <time.h>
#include <stdio.h>
int main()
{
int a = 10;
int num = 20;
int c = time(0);
while(n--)
{
printf("%d\n", a);
while(!(time(0) - c));
c = time(0);
}
return 0;
}
use time(0) see this example
/* timer.c */
#include <stdio.h>
#include <time.h>
void delay_sec( int seconds ){
clock_t endwait;
endwait = clock () + seconds * CLOCKS_PER_SEC;
while (clock() < endwait) {}
}
int main (void){
time_t rawtime, ini_time, now;
struct tm *ptm;
time ( &ini_time );
for(;;){
time ( &rawtime );
//ptm = gmtime ( &rawtime );
//printf ("%2d:%02d:%02d\n", ptm_2->tm_hour, ptm_2->tm_min, ptm_2->tm_sec);
now = rawtime - ini_time;
ptm = gmtime ( &now );
printf ("%2d:%02d:%02d\n", ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
delay_sec(1);
}
return 0;
}
I believe you know 1000 Milliseconds equals to 1 Second.
#include <stdio.h>
#include <time.h>
#define mydelay 1000
void delay(int mseconds)
{
clock_t wait = mseconds + clock();
while (wait > clock());
}
int main()
{
int i=100;
while(1)
{
printf("%d\n",i);
delay(mydelay);
}
return 0;
}
A simple example which prints the value of the variable a for every 1 sec:
#include<stdio.h>
void main(void)
{
int a = 10;
while(a--)
{
printf("Value of a = %d\n", a);
sleep(1);
}
}
Output:
Value of a = 9
...
value of a = 0

Convert Linux C Char Array to Int

need some advice on this one as im struggling abit and cannot figure it out.
i have a file that gets updated on a PC to indicate a system ran and what time it ran. i am writing a very simple linux console app (will eventually be a nagios plugin). that reads this file and responds depending on what it found within the file.
i am a total newbie to programming on Linux and using C so please be patient and if you would explain any answers it would really be appreciated.
basically i want to convert a char array containing 5 characters into an integer, however the 5th char in the array is always a letter. so technically all i want to-do is convert the first 4 chars in the array to a integer... how?? ive tried multiple ways with no success, my problem is that presently i do not have a good grasp of the language so have no real ideas on what it can and cannot do.
here is the source to my program.
basically the buf array will be holding a string taken from the file that will look something like this
3455Y (the number will be random but always 4 chars long).
Sorry for the poor formatting of the code, but i cannot get this stupid window for love nor money to format it correctly....
include <fcntl.h>
include <unistd.h>
include <stdio.h>
include <stdlib.h>
include <time.h>
include <string.h>
define COPYMODE 0644
int main(int argc, char *argv[])
{
int i, nRead, fd;
int source;
int STATE_OK = 0;
int STATE_WARNING = 1;
int STATE_CRITICAL = 2;
int STATE_UNKNOWN = 3;
int system_paused = 0;
char buf[5];
int testnumber;
if((fd = open(argv[1], O_RDONLY)) == -1)
{
printf("failed open : %s", argv[1]);
return STATE_UNKNOWN;
}
else
{
nRead = read(fd, buf, 5);
}
close(source);
if (buf[4] == 'P')
{
printf("Software Paused");
return STATE_WARNING;
}
else
{
return STATE_OK;
}
time_t ltime; /* calendar time */
struct tm *Tm;
ltime=time(NULL); /* get current cal time */
Tm=localtime(&ltime);
int test;
test = Tm->tm_hour + Tm->tm_min;
printf("%d", test);
printf("%d", strtoi(buf));
}
You can use sscanf to do the job:
int num = 0;
sscanf(buf, "%4d", &num);
Then num should hold the number from the line in the file.
You can use atoi
atoi requires one char * argument and returns an int.
If the string is empty, or first character isn't a number or a minus sign, then atoi returns 0.If atoi encounters a non-number character, it returns the number formed up until that point
int num = atoi(buf);
if you want to convert the first four characters of a string to an integer do this:
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdint.h>
uint8_t convertFirstFourChars(char * str, uint32_t *value){
char tmp[5] = {0};
strncpy((char *) tmp, str, 4);
*value = strtoul(tmp);
return errno;
}
then call / test this function like this
#include <stdint.h>
#include <stdio.h>
int main(int argc, char **argv){
char test1[5] = "1234A";
char test2[5] = "ABCDE";
uint32_t val = 0;
if(convertFirstFourChars((char *) test1, &val) == 0){
printf("conversion of %s succeeded, value = %ld\n", test1, val);
}
else{
printf("conversion of %s failed!\n", test1);
}
if(convertFirstFourChars((char *) test2, &val) == 0){
printf("conversion succeeded of %s, value = %ld\n", test2, val);
}
else{
printf("conversion of %s failed!\n", test2);
}
return 0;
}
FWIW, don't use atoi(...) because it converts any string to an integer regardless of its validity as a number. atoi("foo") === 0.
this is as much of your code as I was able to recover from the formatting:
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <time.h>
#define COPYMODE 0644
int main(int argc, char *argv[])
{
int i, nRead, fd;
int source;
int STATE_OK = 0;
int STATE_WARNING = 1;
int STATE_CRITICAL = 2;
int STATE_UNKNOWN = 3;
int system_paused = 0;
char buf[5];
int testnumber;
if((fd = open(argv[1], O_RDONLY)) == -1)
{
printf("failed open : %s", argv[1]);
return STATE_UNKNOWN;
}
else
{
nRead = read(fd, buf, 5);
}
close(source);
if (buf[4] == 'P')
{
printf("Software Paused");
return STATE_WARNING;
} else {
return STATE_OK;
}
time_t ltime; /* calendar time /
struct tm Tm;
ltime=time(NULL); / get current cal time */
Tm=localtime(&ltime);
int test;
test = Tm->tm_hour + Tm->tm_min;
printf("%d", test);
printf("%d", strtoi(buf));
}
this is the version that does what you specified:
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <time.h>
#define COPYMODE 0644
int main(int argc, char *argv[])
{
int i, nRead, fd;
int source;
int STATE_OK = 0;
int STATE_WARNING = 1;
int STATE_CRITICAL = 2;
int STATE_UNKNOWN = 3;
int system_paused = 0;
char buf[5];
int testnumber;
if((fd = open(argv[1], O_RDONLY)) == -1)
{
printf("failed open : %s", argv[1]);
return STATE_UNKNOWN;
}
else
{
nRead = read(fd, buf, 5);
}
close(source);
if (buf[4] == 'P')
{
printf("Software Paused");
return STATE_WARNING;
}/* else {
return STATE_OK;
buf[4] = 0;
} */
time_t ltime; /* calendar time */
struct tm *Tm;
ltime=time(NULL); /* get current cal time */
Tm=localtime(&ltime);
int test;
test = Tm->tm_hour + Tm->tm_min;
printf("%d\n", test);
printf("%d\n", atoi(buf));
}
The biggest problem with your code was the if statement with the returns in each branch, insuring that nothing after the if statement was ever executed.

Resources