C语言之“拒绝scanf,从我做起”

大家好,我来了,我是萌杰尔

前段时间,我想实现一个命令行工具(类似cmd.exe那种的),于是建起了万年不用的C语言,写起了输入输出。

问题就出在这里了,我用的scanf函数不接受空字符,只要我不输入东西,按回车还是无法结束,这我能忍???

作为一个在计算机这块混了八年的混子,我肯定有我的办法,可能不一定号,但是可以解决当下的这个问题。

我想,很多朋友已经知道怎么办了,但是还是有些萌新遇到这种问题不知道如何解决,那我今天就来讲一讲吧。

解题思路

我的思路是使用一个循环,通过getchar函数持续不断的接收字符,然后把字符存储到字符串中。

说干就干,昨天晚上我花了一点时间实现这个功能,下面展示一下我的代码。

#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[])
{
	//外层循环,让程序每次执行完一个命令就返回到初始地方重新输入命令
    while (1)
    {
    	//命令字符串
        char command[128];
        //累加器,表示当前输入的字符对应命令字符串中的下标
        int scannerIndex = 0;
        //清空命令字符串(避免缓冲区问题)
        memset(command, 0, sizeof(command));
        //打印Command
        printf("Command > ");
        //里层循环,接收字符
        while (1)
        {
        	//接收字符暂时存储位置
            char buff = getchar();
            //判断该字符是否为回车,如果是,就让累加器归零并且退出循环
            if (buff == '\n')
            {
                scannerIndex = 0;
                break;
            }
            //如果不是,就将输入的字符保存到命令字符串中
            command[scannerIndex] = buff;
            //累加器的值增加
            scannerIndex++;
        }
        //判断命令是否为空,如果为空,让循环停止重新执行
        if (strlen(command) == 0)
            continue;
		//这下面可以开始写命令操作的内容了
		//Code Here
		

    }
    return 0;
}

执行结果如下
C语言之“拒绝scanf,从我做起”
可以看到当我留空时会直接重新执行,解决了scanf的问题。

我是那种更文只更到一半的人吗?当然不是,那么我们继续实现这个Command程序。

接下来我要增加一个分割命令名称和参数的功能,与cmd和其他众多命令行工具一样,该命令行的命令和参数也是通过空格分隔开来,那就好办了,我在这里举个栗子,我的命令只有一个参数,比如echo命令,我只需要输出第一个参数即可。

那么我就来写一下分割命令的代码。

//由于strtok这个分割字符串的函数会破坏原始字符串,所以这里我重新声明一个buff字符串
char buff[128];
//清空buff字符串
memset(buff, 0, sizeof(buff));
//将command字符串中的内容复制给buff字符串
strcpy(buff, command);
//声明key,value字符串。key时命令,value是参数。
char key[64], value[64];
//清空key字符串
memset(key, 0, sizeof(key));
//清空value字符串
memset(value, 0, sizeof(value));
//截取' '(空格)之前的内容给key
strcpy(key, strtok(buff, " "));
//截取' '(空格)之后的内容给value,strtok函数第一个参数留空是接着上一次的继续截取
strcpy(value, strtok(NULL, " "));

到这里,其实我们已经把命令和参数分别保存到key和value中了

那么我就可以开始判断这是个什么命令,程序应该怎么做。

其实很简单,从这里开始就是if-else之类的了

//如果命令是echo,输出参数
if (!strcmp(key, "echo"))
{
    printf("%s\n", value);
//如果命令是list,输出“该命令正在开发中”
} else if (!strcmp(key, "list"))
{
    printf("This command is developing!\n");
//如果都不是,输出“错误的命令”
} else
{
    printf("Error command!\n");
}

上面的都写完之后,我们可以编译,执行该源码,最终得到的结果应该是如下的
C语言之“拒绝scanf,从我做起”
如上图,当我输入echo hello的时候程序输出了hello

输入list .\的时候输出This command is developing!

出入其他命令则输出Error command!

最终源码展示

#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[])
{
    while (1)
    {
        char command[128];
        int scannerIndex = 0;
        memset(command, 0, sizeof(command));
        printf("Command > ");
        while (1)
        {
            char buff = getchar();
            if (buff == '\n')
            {
                scannerIndex = 0;
                break;
            }
            command[scannerIndex] = buff;
            scannerIndex++;
        }
        //Code Here
        if (strlen(command) == 0)
            continue;
        // printf("Your Command Is %s\n", command);
        
        /***
         * splice the command
         * key: command
         * value: argument
         **/
        char buff[128];
        memset(buff, 0, sizeof(buff));
        strcpy(buff, command);
        char key[64], value[64];
        memset(key, 0, sizeof(key));
        memset(value, 0, sizeof(value));
        strcpy(key, strtok(buff, " "));
        strcpy(value, strtok(NULL, " "));
        
        /***
         * run command
         **/
        if (!strcmp(key, "echo"))
        {
            printf("%s\n", value);
        } else if (!strcmp(key, "list"))
        {
            printf("This command is developing!\n");
        } else
        {
            printf("Error command!\n");
        }

    }
    return 0;
}

感谢大家阅读我的文章,如果你有其他的观点或思路,可以在我的文章下面评论哦

我的微信群,欢迎大家加入
C语言之“拒绝scanf,从我做起”

上一篇:C# 爬取网易Buff进行购买


下一篇:MLX90614红外温度模块驱动