Simulate Typing with This C Program
I recently created a video demonstration of how to do some work at the command line, but as I tried to record my video, I kept running into problems. I'm just not the kind of person who can type commands at a keyboard and talk about it at the same time. I quickly realized I needed a way to simulate typing, so I could create a "canned" demonstration that I could narrate in my video.
After doing some searching, I couldn't find a command on my distribution that would simulate typing. I wasn't surprised; that's not a common thing people need to do. So instead, I rolled my own program to do it.
Writing a program to simulate typing isn't as difficult as it first
might seem. I needed my program to act like the echo
command, where it displayed
output given as command-line parameters. I added command-line options so
I could set a delay between the program "typing" each letter, with an
additional delay for spaces and newlines. The program basically did this
the following
for each character in a given string:
- Insert a delay.
- Print the character.
- Flush the output buffer so it shows up on screen.
First, I needed a way to simulate a delay in typing, such as someone
typing slowly, or pausing before typing the next word or pressing
Enter. The C function to create a delay is usleep(useconds_t
usec)
. You use
usleep()
with the number of microseconds you want your program to
pause. So if you want to wait one second, you would use
usleep(1000000)
.
Working in microseconds means too many zeroes for me to type, so I wrote a
simple wrapper called msleep(int millisec)
that does the same thing
in milliseconds:
int
msleep (int millisec)
{
useconds_t usec;
int ret;
/* wrapper to usleep() but values in milliseconds instead */
usec = (useconds_t) millisec *1000;
ret = usleep (usec);
return (ret);
}
Next, I needed to push characters to the screen after each
delay. Normally, you can use putchar(int char)
to send a single character
to standard output (such as the screen), but you won't actually see the
output until you send a newline. To get around this, you need to flush the
output buffer manually. The C function fflush(FILE *stream)
will flush an
output stream for you. If you put a delay()
before each
fflush()
, it will
appear that someone is pausing slightly between typing each character.
Here's a simple function I wrote to simulate typing. The
echodelay()
function takes parameters that describe the delay before printing
characters, spaces and newlines. The last parameter is the string to
print. The function loops through the string and pauses before printing
each character, then flushes the output buffer. The effect is that each
character seems to appear one at a time, as though someone were typing
at a keyboard:
void
echodelay (int chdelay, int spdelay, int nldelay, char *string)
{
int pos = 0;
/* add a delay between printing each character in the string,
depending on the character */
do
{
switch (string[pos])
{
case '\0': /* new line */
msleep (nldelay);
break;
case ' ': /* space */
msleep (spdelay);
break;
default: /* character */
msleep (chdelay);
break;
}
putchar (string[pos]);
fflush (stdout);
}
while (string[pos++] != '\0');
}
With that function, it's a simple process to write a parent
main()
function to parse the command line, set the different delays, and call the
echodelay()
function to generate the output with the
appropriate delays:
/* echodelay.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void echodelay (int chdelay, int spdelay, int nldelay,
↪char *string);
int msleep (int millisec);
int atoipos (char *string);
int
main (int argc, char **argv)
{
int opt;
int chdelay = 0, spdelay = 0, nldelay = 0;
/* parse command line */
while ((opt = getopt (argc, argv, "c:s:n:")) != -1)
{
switch (opt)
{
case 'c': /* -c nnn */
chdelay = atoipos (optarg);
break;
case 's': /* -s nnn */
spdelay = atoipos (optarg);
break;
case 'n': /* -n nnn */
nldelay = atoipos (optarg);
break;
default: /* unrecognized option */
fprintf (stderr, "Usage: echodelay [-c millisec]
↪[-s millisec] [-n millisec] [text..]\n");
exit (1);
break;
}
}
/* pass all remaining options as text to echodelay() */
for (opt = optind; opt < argc; opt++)
{
echodelay (chdelay, spdelay, nldelay, argv[opt]);
putchar (' ');
}
putchar ('\n');
exit (0);
}
void
echodelay (int chdelay, int spdelay, int nldelay, char *string)
{
...
}
int
msleep (int millisec)
{
...
}
int
atoipos (char *string)
{
int val;
/* wrapper to atoi() but always a positive return value */
val = atoi (string);
if (val < 0)
{
val = 0;
}
return (val);
}
And compile it like this:
gcc -Wall -o echodelay echodelay.c
In a shell script, I had commands to print a "prompt", then simulate typing a command before executing the command—for example, this command to generate a file of random size in your /tmp directory:
echo -n 'prompt$'
echodelay -c 500 -s 1000 -n 2000 'ls -lh /tmp'
ls -lh /tmp
This is a fairly straightforward C program to simulate typing. I wrote it quickly to do a single job, but it works as a solution to simulate typing while I narrated my how-to video. In this way, I didn't need to think about what I was typing while I was trying to describe it. If you need to simulate typing for a similar task, I hope you find this program useful.