NO

Author Topic: wait utility, process command line, check if a keyboard key has been pressed  (Read 2189 times)

fallen

  • Guest
This utility is called wait.exe. I use this utility in batch files to allow a timed pause to occur. It will default to a delay of 10 seconds or it will take a parameter of seconds and it would do either of two things; wait for the number of seconds to elapse and return, or if a keyboard key is pressed, it would return.

I left all my "will this work" and debugging stuff in so people can play around with it like I did. I plan on adding the getopt ftn to process the argv options and adding the functionally of passing in a new string to replace the default message as an option. But, it may take a while, so thought I would go ahead and post the code now, since a while for me have in the past been between a few hours and a few years!

This utility currently works, so you can take it out for a drive. Can it be better, you bet, can't wait to see the code enhancements. Everybody loves to see the code the guru's code or enhance, so people (non-guru and guru) feel free to enhance the code to your hearts content. If you have enhancements, please don't keep them to yourself, post them. Remember, people always talk more about non-guru code than they do the guru's code!

Here is version 1 of wait.exe
Code: [Select]
#include <stdio.h> //  For printf
#include <stdlib.h> //  For EXIT_FAILURE, EXIT_SUCCESS
#include <time.h>
#include <sys/timeb.h>
#include <conio.h> // For _kbhit
#include <ctype.h>
#include <string.h> //  For strcmp


void doUsage(void)
{
  printf ("wait.exe utility v1.0\n" \
  "Usage  :  wait.exe [delay in seconds]\n" \
  "options:  -h -H /h /H -? /? -help -HELP ?help ?HELP\n" \
  "Notes:  This default delay is 10 seconds.\n" \
  "        If a key is pressed before the end of the delay period\n" \
    "        the program will stop.\n" \
  "        Author: Fletcher Allen   Date: 1/20/2015\n" \
    "        This program is provided as open source.\n");
}


int main (int argc, char* argv[])

struct _timeb now;
struct _timeb then;

int numofsecs = 10; //default delay in seconds
double timedifference = 0; //holds the time difference in seconds between the two times for the do-while loop

//int ireturn = 0; //captures return values
//int i; //used in for loops

/*    printf("Number of arguments: %d\n\n",argc);
    printf("Name of program %s\n\n",argv[0]);
     
    for (i=1; i<argc && argc > 1; i++)
      printf("User parameter = %d : %s\n",i,argv[i]);
   
    printf("\n\n");
*/

/*    if (argv[1]) {
      if (strcmp ("-?", argv[1]) == 0)
{
printf ("1 User is asking for help.\n" );
    doUsage ();
    return EXIT_SUCCESS;
//ireturn = system("pause");
}
} */

   if (argv[1])
{
   //  If no arguments are given in DOS command line, then print Usage.
if (argv[1] == "-h" || argv[1] == "/h" || argv[1] == "-H" || argv[1] == "/H" ||
argv[1] == "-?" || argv[1] == "/?" ||
    argv[1] == "-help" || argv[1] == "/help" || argv[1] == "-HELP" || argv[1] == "/HELP"  )
{
//printf ("1 User is asking for help.\n" );
    doUsage ();
    return EXIT_SUCCESS;
}
else
{
//printf("3 Argv[1] value: %s   with int value of: %d.\n",argv[1],  atoi(argv[1]));
if (atoi(argv[1]) != 0)
{
//printf("4 argv[1] %s is a digit value.\n",argv[1]);
numofsecs = atoi(argv[1]);
//ireturn = system("pause");
}
/*else
{
printf("5 argv[1] %s is a not a digit value.\n",argv[1]);
} */

/*
char *s;
char *t;
printf("*s value: %s.\n",s);
printf("*t value: %s.\n",t);
s = '\0';
t = argv[1];
printf("*s value: %s.\n",(char *)*s);
printf("*t value: %s.\n",(char *)*t);
while(*t != '\0')
*s++ = *t++;
*s = '\0';

printf("*s value: %s.\n",(char *)*s);
*/


/* for(i = 0; argv[1][i] != '\0'; i++)
{
//s[i] = argv[1][i];
if (isdigit(argv[1][i]) != 0)
{
printf("6 argv[1][i] %u is a digit value.\n",argv[1][i]);
}
else
{
printf("7 argv[1][i] %u is a not a digit value.\n",argv[1][i]);
}
} */

//s[i] = '\0';

/*printf("sizeof(argv[1]) value: %d.\n",strlen(argv[1]));
    for (i=0; i<sizeof(argv[1]); i++)
{
if (isdigit(argv[1][i]) != 0)
{
printf("argv[1][i] %u is a digit value.\n",argv[1][i]);
}
else
{
printf("argv[1][i] %u is a not a digit value.\n",argv[1][i]);
}
} */
//ireturn = system("pause");



/* Once again, these code fragments are being written in a rather compressed way. To make it easier to see what's going on, here are alternate versions of strcpy, which don't bury the assignment in the loop test. First we'll use array notation:

void strcpy(char s[], char t[])
{
int i;
for(i = 0; t[i] != '\0'; i++)
s[i] = t[i];
s[i] = '\0';
}

Note that we have to manually append the '\0' to s after the loop. Note that in doing so we depend upon i retaining its final value after the loop, but this is guaranteed in C, as we learned in Chapter 3.

Here is a similar function, using pointer notation:

void strcpy(char *s, char *t)
{
while(*t != '\0')
*s++ = *t++;
*s = '\0';
}

Again, we have to manually append the '\0'. Yet another option might be to use a do/while loop.

*/
}
}
    //ireturn = system("pause");



_ftime(&now); //get the current time
//_ftime(&then);
then = now; //set the later time


//printf ("8 Wait for %4d seconds.\n", numofsecs );

//printf ("9 xx: %10i    now.time: %u     then.time: %12u \n", (int)xx, now.time, then.time );
    //ireturn = system("pause");

printf ("Waiting for %i seconds...\n", (int)numofsecs); //display the default wait.exe message.

do
{
timedifference = difftime(then.time, now.time);
//printf ("10 xx: %i    now.time: %12d     then.time: %12u \n", (int)numofsecs, now.time, then.time );
_ftime(&then);

if ( _kbhit() != 0)
return 3;

} while (timedifference <= numofsecs);

return 0;
}


I had help with my questions from czerny in the Beginner section, which also posted this code for me, so I thought I would post it here as well. czerny comments were, "This is another small example. If no parameter is given, this waits until keypressed."
Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>

int main(int argc, char **argv)
{
clock_t start;
double stop;

if (argc == 2)
{
stop = strtod(argv[1], NULL);
if (stop > 0.0) {
start = clock();
while (!_kbhit())
{
if ((double)(clock() - start)/CLOCKS_PER_SEC >= stop) break;
}
}
else puts("usage: wait [seconds]");
}
else while (!_kbhit());

return 0;
}


czerny

  • Guest
I will correct my own code:

If an error occured, the program should return a non-null value.

So replace
Code: [Select]
else puts("usage: wait [seconds]");with
Code: [Select]
else {
  puts("usage: wait [seconds]");
  return 1;
}

czerny

  • Guest
fallen: Two annotations!

The ide has the ability to format your code:
Ctrl-a --> Source --> Convert to --> Formatted C code

Your little tool is most likely used in a batch file. Batch files often do their job by piping its output into an other file.
In such cases I do not like further unnecessary output from the commands used. So I wouldn't do such an output like the ellapsed time by default (my be a switch -verbose). An other option could be, not to use stdout but stderr as output for status and error messages.

fallen

  • Guest
The comments were good. They spurred me on to add the getopt code to check for input parameters. Version 2.0 of the little wait program will now accept input parameters. I have this setup as a 32-bit console program, that way I don't have two different versions, since there is no advantage that I can see for it being as a 64-bit console program. That's because in my environment, I work on both 32-bit and 64-bit PC/servers.

The getopt code shows how to accept both a string and a number as input parameters and use them in your program.

Code: [Select]
#include <stdio.h> //  For printf
#include <stdlib.h> //  For EXIT_FAILURE, EXIT_SUCCESS
#include <time.h>
#include <sys/timeb.h>
#include <conio.h> // For _kbhit
#include <ctype.h>
#include <string.h>
#include <getopt.h>
#include <stdbool.h>  // For true and false

#define PACKAGE "wait.exe"
#define VERSION "2.0"

#if __STDC__
extern int getopt(int, char *const *, const char *);
#else
extern int getopt();
#endif

void doUsage(int exval);

int main(int argc, char *argv[])
{

struct _timeb now;
struct _timeb then;

int numofsecs = 10; //default delay in seconds
double timedifference = 0; //holds the time difference in seconds between the two times for the do-while loop

char *outmessage = '\0';

int nomessage = false;
int newmessage = false;
int opt = 0;

while ((opt = _getopt(argc, argv, ":hHvns:m:")) != -1)
{
//printf("you entered: `%c'\n", opt);
switch (opt)
{
case 'h':
case 'H':
doUsage(0);
break;
case 'v':
fprintf(stdout, "%s %s\n", PACKAGE, VERSION);
exit(0);
break;
case 'n':
//printf("you entered -n option for no message.\n");
nomessage = true;
break;
case 's':
//printf("you entered %d seconds.\n", atoi(optarg));
numofsecs = atoi(optarg);
break;
case 'm':
//printf("you entered new message of: \"%s\"\n", optarg);
outmessage = optarg;
//printf("outmessage: \"%s\"\n", outmessage);
newmessage = true;
break;
case ':': /* -s or -m without operand */
fprintf(stderr, "Option -%c requires an operand\n\n", optopt);
doUsage(1);
break;
case '?':
fprintf(stderr, "%s: Error - No such option: `%c'\n\n", PACKAGE, optopt);
doUsage(1);
break;
} /* switch */
} /* while */

/* this will catch any extra parameters passed to the program without a leading - */
if ((argc - optind) != 0)
{
//printf("argc: %4d   optind: %d\n", argc, optind);
fprintf(stderr, "%s: Error - invalid/unknown option(s)\n\n", PACKAGE);
doUsage(1);
}

_ftime(&now); //get the current time
//_ftime(&then);
then = now; //set the later time

//printf ("8 Wait for %4d seconds.\n", numofsecs );

//printf ("9 xx: %10i    now.time: %u     then.time: %12u \n", (int)xx, now.time, then.time );
//ireturn = system("pause");

if (nomessage)
{
;
}
else if (newmessage)
{
printf("%s\n", outmessage);
}
else
{
printf("Waiting for %i seconds...\n", (int)numofsecs); //display the default wait.exe message.
}

do
{
timedifference = difftime(then.time, now.time);
//printf ("10 xx: %i    now.time: %12d     then.time: %12u \n", (int)numofsecs, now.time, then.time );
_ftime(&then);

if (_kbhit() != 0)
return 3;

} while (timedifference <= numofsecs);

return 0;
}

void doUsage(int exval)
{
printf("%s utility %s\n", PACKAGE, VERSION);
printf("Usage  :  %s [-h] [-H] [-v] [-s delay in seconds] [-n] [-m \"new message\"]\n\n", PACKAGE);
printf("options:  -h or -H will display this help messaage.\n"
"          -v will display this program version information.\n"
"          -s followed by the number of seconds you want the program to wait.\n"
"          -n no message will be displayed.\n"
"          -m followed by the message to be displayed.\n"
"             The new message must be enclosed by double qoutes.\n"
"             ex. \"Waiting for you to press a key.\"\n\n"
"Notes:  This default delay is 10 seconds.\n"
"        The default message is: \"Waiting for 10 seconds...\"\n"
"        If a key is pressed before the end of the delay period\n"
"        the program will stop.\n\n"
"        Author: Fletcher Allen   Date: 1/29/2015\n"
"        This program is provided as open source.\n");

exit(exval);
}