c - 如何让这个 shell 解析 C 语言中带有引号的语句?

标签 c linux parsing quotes

我正在尝试让这个 shell 解析。我如何让程序以某种方式实现解析,以便根据开始和结束引号解析引号中的命令并将其视为一个标记?在我打印出标记的第二个 while 循环中,我认为我需要放置某种 if 语句,但我不太确定。非常感谢任何反馈/建议。

#include <stdio.h>               //printf
#include <unistd.h>              //isatty
#include <string.h>              //strlen,sizeof,strtok

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

    int MaxLength = 1024;         //size of buffer
    int inloop = 1;               //loop runs forever while 1
    char buffer[MaxLength];       //buffer
    bzero(buffer,sizeof(buffer)); //zeros out the buffer
    char *command;                //character pointer of strings
    char *token;                  //tokens
    const char s[] = "-,+,|, ";

    /* part 1 isatty */
    if (isatty(0))
    {

        while(inloop ==1)                // check if the standard input is from terminal
        {
            printf("$");
            command = fgets(buffer,sizeof(buffer),stdin);  //fgets(string of char pointer,size of,input from where
            token =  strtok(command,s);

            while (token !=NULL){

                printf( " %s\n",token);

                token = strtok(NULL, s);       //checks for elements       
            }


            if(strcmp(command,"exit\n")==0)
                inloop =0;

        }      

    }
    else 
        printf("the standard input is NOT from a terminal\n");

    return 0;
}

最佳答案

对于任意命令行语法,strtok 不是最好的函数。它适用于简单的情况,其中单词由特殊字符或空格分隔,但有时您想要将类似 ls>out 的内容拆分为三个标记。 strtok 无法处理这个问题,因为它需要在某处放置它的终止零。

这是一个快速而肮脏的自定义命令行解析器:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

int error(const char *msg)
{
    printf("Error: %s\n", msg);
    return -1;
}

int token(const char *begin, const char *end)
{
    printf("'%.*s'\n", end - begin, begin);
    return 1;
}

int parse(const char *cmd)
{
    const char *p = cmd;
    int count = 0;

    for (;;) {
        while (isspace(*p)) p++;
        if (*p == '\0') break;

        if (*p == '"' || *p == '\'') {
            int quote = *p++;
            const char *begin = p;

            while (*p && *p != quote) p++;
            if (*p == '\0') return error("Unmachted quote");
            count += token(begin, p);
            p++;
            continue;
        }

        if (strchr("<>()|", *p)) {
            count += token(p, p + 1);
            p++;
            continue;
        }

        if (isalnum(*p)) {
            const char *begin = p;

            while (isalnum(*p)) p++;
            count += token(begin, p);
            continue;
        }

        return error("Illegal character");
    }

    return count;
}

此代码理解由空格分隔的单词、由单引号或双引号分隔的单词以及单字符运算符。它不理解引号内的转义引号和非字母数字字符,例如单词中的点。

代码不难理解,您可以轻松扩展它以理解双字符运算符,例如 >>> 或注释。

如果你想转义引号,你必须识别 parse 中的转义字符并取消转义它以及 token 中可能的其他转义序列。

关于c - 如何让这个 shell 解析 C 语言中带有引号的语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21918728/

相关文章:

c - 如何获取txt中的内容并将其存储在c中的数组中

c - 发送文件(客户端到服务器和服务器到客户端)

linux - 搜索词然后搜索下一个词然后追加

python - 如何将文本格式列表转换为python列表

c - 在 C 中读取具有可变列数的空格分隔文件

这里可以使用 stringize 宏吗?

java - Rsync 命令在 Java 中不起作用

c++ - 输入大字符串的最快方法?

C - 将 argv 的值分配给变量

c - 正确释放动态分配的结构