使用此 C 程序模拟打字
我最近创建了一个视频演示,展示如何在命令行上完成一些工作,但是当我尝试录制视频时,我不断遇到问题。我不是那种可以一边在键盘上打字一边谈论它的人。我很快意识到我需要一种模拟打字的方法,这样我就可以创建一个“预制”演示,以便在我的视频中进行解说。
在搜索一番后,我没有在我的发行版中找到可以模拟打字的命令。我并不感到惊讶;这不是人们需要做的常见事情。所以,我编写了自己的程序来完成这项工作。
编写一个模拟打字的程序并不像最初看起来那么困难。我需要我的程序像 echo
命令一样工作,它可以显示作为命令行参数给出的输出。我添加了命令行选项,以便我可以设置程序“打字”每个字母之间的延迟,以及空格和换行符的额外延迟。该程序基本上对给定字符串中的每个字符执行以下操作
- 插入延迟。
- 打印字符。
- 刷新输出缓冲区,使其显示在屏幕上。
首先,我需要一种模拟打字延迟的方法,例如某人打字缓慢,或在键入下一个单词或按 Enter 键之前暂停。用于创建延迟的 C 函数是 usleep(useconds_t usec)
。您可以使用 usleep()
以及您希望程序暂停的微秒数。因此,如果您想等待一秒钟,您可以使用 usleep(1000000)
。
以微秒为单位工作意味着我需要输入太多的零,所以我编写了一个名为 msleep(int millisec)
的简单包装器,它以毫秒为单位执行相同的操作
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);
}
接下来,我需要在每次延迟后将字符推送到屏幕。通常,您可以使用 putchar(int char)
将单个字符发送到标准输出(例如屏幕),但在发送换行符之前,您实际上看不到输出。为了解决这个问题,您需要手动刷新输出缓冲区。C 函数 fflush(FILE *stream)
将为您刷新输出流。如果您在每个 fflush()
之前放置一个 delay()
,则看起来好像有人在键入每个字符之间稍微停顿了一下。
这是我编写的一个简单的函数来模拟打字。echodelay()
函数接受描述打印字符、空格和换行符之前的延迟的参数。最后一个参数是要打印的字符串。该函数循环遍历字符串并在打印每个字符之前暂停,然后刷新输出缓冲区。效果是每个字符似乎一次出现一个,就像有人在键盘上打字一样
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');
}
有了这个函数,编写一个父 main()
函数来解析命令行,设置不同的延迟,并调用 echodelay()
函数来生成具有适当延迟的输出,这是一个简单的过程
/* 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);
}
并像这样编译它
gcc -Wall -o echodelay echodelay.c
在 shell 脚本中,我有命令来打印“提示符”,然后模拟在执行命令之前键入命令——例如,此命令用于在您的 /tmp 目录中生成一个随机大小的文件
echo -n 'prompt$'
echodelay -c 500 -s 1000 -n 2000 'ls -lh /tmp'
ls -lh /tmp
这是一个相当简单的 C 程序来模拟打字。我快速编写它来完成一项工作,但它可以作为在我解说操作视频时模拟打字的解决方案。这样,当我想描述它时,我不需要考虑我正在打字的内容。如果您需要为类似的任务模拟打字,我希望您发现此程序有用。