c - 解析 C 语言中的 bash 命令输入

标签 c string bash parsing

我正在用 C 语言编写一个简单的 shell。该 shell 的一部分使用了 bash 命令,需要将这些命令拆分为字符数组,以便我可以正确执行这些命令。作为一个简单的概念证明,我想制作一个 C 程序来检查它是否是单词或特殊字符( |&>< )。

以下是其外观的示例:

input a command: cat hello.txt |wc -l
---output---
cat
hello.txt
|
wc
-l

到目前为止,我已经让所有情况都可以工作,例如,除了一个异常(exception),那就是当我执行 |wc l 中的特殊字符时。其中字母位于特殊字符之后。这是我当前的输出:

input a command: cat hello.txt |wc -l
---output---
cat
hello.txt
|wc
-l

下面是我的代码,我尝试添加特殊情况、删除情况,但似乎没有任何效果正常。我该如何解决这个问题?

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

#define ALPHABET 1000
#define LESS_THAN 60
#define GREATER_THAN 62
#define AMPERSAND 38
#define PIPE 124
#define WHITESPACE 32
#define NEWLINE 10
#define MYCOPOUT 9999

#define CAPITALS(i) ((i >= 65) && (i <= 90))
#define LOWERS(i) ((i >= 97) && (i <= 122))
#define BACKSLASH(i) i == 47

int classify(int i)
{
    if (CAPITALS(i) || LOWERS(i) || BACKSLASH(i))
        return ALPHABET;
    return i;
}

char isSpecial(int i)
{
    return (i == LESS_THAN) ||(i == GREATER_THAN) || (i == AMPERSAND) || (i == PIPE);
}

char isWhiteSpace(int i)
{
    return (i == WHITESPACE) || (i == NEWLINE);
}

void PRINT_N_NEW(int c, int last)
{
    if (isWhiteSpace(last)) {
        printf("%c",c);
    } else if(isSpecial(last)) {
        printf("\n%c\n",c);
    } else {
        printf("%c\n", c);
    }
    last = c;
}

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

    int i;
    int last = MYCOPOUT;
    while ( (i = getchar()) != EOF){
        switch(classify(i)){
            case ALPHABET:
                printf("%c",i);
                last = i;
                break;
            case LESS_THAN:
                PRINT_N_NEW(i,last);
                break;
            case GREATER_THAN:
                PRINT_N_NEW(i,last);
                break;
            case AMPERSAND:
                PRINT_N_NEW(i,last);
                break;
            case PIPE:
                PRINT_N_NEW(i,last);
                break;
            case WHITESPACE:
                printf("\n");
                last = i;
                break;
            case NEWLINE:
                printf("\n");
                last = i;
                break;
            default:
                printf("%c",i);
                last = i;
                break;
        }
    }
    return 0;
}

最佳答案

您并不是每次循环时都设置last,只有在switch的某些情况下才设置。打印普通字符时还应该使用 PRINT_N_NEW ,以便它会测试最后一个字符并在其前面添加换行符。最后,如果您要打印的字符是特殊字符,则需要在其前面打印换行符。

PRINT_N_NEW 末尾执行 last = c 是没有意义的。这不会在调用者中设置变量,它只是设置本地副本。

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

#define ALPHABET 1000
#define LESS_THAN 60
#define GREATER_THAN 62
#define AMPERSAND 38
#define PIPE 124
#define WHITESPACE 32
#define NEWLINE 10
#define MYCOPOUT 9999

#define CAPITALS(i) ((i >= 65) && (i <= 90))
#define LOWERS(i) ((i >= 97) && (i <= 122))
#define BACKSLASH(i) i == 47

int classify(int i)
{
    if (CAPITALS(i) || LOWERS(i) || BACKSLASH(i))
        return ALPHABET;
    return i;
}

char isSpecial(int i)
{
    return (i == LESS_THAN) ||(i == GREATER_THAN) || (i == AMPERSAND) || (i == PIPE);
}

char isWhiteSpace(int i)
{
    return (i == WHITESPACE) || (i == NEWLINE);
}

void PRINT_N_NEW(int c, int last)
{
    if (isWhiteSpace(last)) {
        printf("%c",c);
    } else if(isSpecial(last) || isSpecial(c)) {
        printf("\n%c",c);
    } else {
        printf("%c", c);
    }
}

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

    int i;
    int last = MYCOPOUT;
    while ( (i = getchar()) != EOF){
        switch(classify(i)){
            case ALPHABET:
                PRINT_N_NEW(i, last);
                break;
            case LESS_THAN:
                PRINT_N_NEW(i,last);
                break;
            case GREATER_THAN:
                PRINT_N_NEW(i,last);
                break;
            case AMPERSAND:
                PRINT_N_NEW(i,last);
                break;
            case PIPE:
                PRINT_N_NEW(i,last);
                break;
            case WHITESPACE:
                printf("\n");
                break;
            case NEWLINE:
                printf("\n");
                break;
            default:
                PRINT_N_NEW(i, last);
                break;
        }
        last = i;
    }
    return 0;
}

关于c - 解析 C 语言中的 bash 命令输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28626877/

相关文章:

c - 如何从 C 函数调用 Objective-C 函数

我可以使用两级可变长度参数函数......?

c - SIGSEGV 同时将 1 位图像数据转换为 8 位

c - fgets 应该使用什么大小?

bash - 超时重试 Bash 命令

linux - 如何使用 shell 命令的输出设置期望变量

c - 使用修改后的 ls 执行另一个程序

c - 如果重复则添加字母 C

arrays - 在 SQL Server 中将一列拆分为多列

bash - 将 mplayer 的输出写入 fifo 并读取