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

Posted 萌杰尔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;

执行结果如下

可以看到当我留空时会直接重新执行,解决了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");

上面的都写完之后,我们可以编译,执行该源码,最终得到的结果应该是如下的

如上图,当我输入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++;
        
        if (strlen(command) == 0)
            continue;
            
		//Code Here
        /***
         * 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语言之“拒绝scanf,从我做起”

C语言硬核编程之勾勒空心菱形

专升本c语言学习体会

c语言域34

shell-数组删除

shell-数组删除