2

状況: 文字列引数を取り、それに何かを行う C プログラムがあります (詳細は関係ありません)。EOF、CR、LF などの制御文字を含む文字列を渡したいのですが、自分のターミナルでキーボードを raw 入力モードにします。私の質問は次のとおりです。Cには、何らかの方法で文字を指定または「入力」できる機能がありますか? (たとえば、一部の言語で文字列を作成するときに、文字をスラッシュでエスケープしたり、16 進コードを示したりすることができます。ターミナル内から C プログラムに引数を渡すことに関して、同様のものが存在するかどうか疑問に思っています。具体的にはコマンド ライン引数)。

4

3 に答える 3

1

おそらく、bash でバイナリ データを引数として渡す方法を学びたいと思うでしょう。この質問を参照してください。

C の短いデモを次に示します。プログラムは、渡されたすべての引数を文字ごとに 16 進数で出力します。

/* compile with cc -o binarg binargs.c */

#include <stdio.h>

int main(int argc, char *argv[])
{
    int i;
    char *ip;
    printf("\n");
    for(i=0; i<argc; i++)
    {
        printf("argv[%d]=%s\n",i,argv[i]);
        for(ip=(char*)argv[i]; *ip!=0; ip++)
        {
            printf("0x%02X <-\t`%c'\n",*ip,*ip);
        }
        printf("\n");
    }
    return 0;
}

上記の投稿で説明されているように、それにバイナリ引数を渡しましょう。

./binargs ABC $'\x41\x42\x43' $'\t\n'

結果:

argv[0]=./binargs
0x2E <- `.'
0x2F <- `/'
0x62 <- `b'
0x69 <- `i'
0x6E <- `n'
0x61 <- `a'
0x72 <- `r'
0x67 <- `g'
0x73 <- `s'

argv[1]=ABC
0x41 <- `A'
0x42 <- `B'
0x43 <- `C'

argv[2]=ABC
0x41 <- `A'
0x42 <- `B'
0x43 <- `C'

argv[3]=

0x09 <- `       '
0x0A <- `
'

argv[0] はプログラムbinargs自体 の名前です

argv[1] は通常の文字列「ABC」です

argv[2] は argv[1] と同じですが、16 進数です

argv[3] は、2 つの制御文字のシーケンスです: HT LF

各文字を引用するのに伝統的な Unix の方法を使用していることに注意してください。

./binargs $'\a\b\v\f'  

( argv[0] の部分はスキップしましょう)

argv[1]=


0x07 <- `'
0x08 <- '
0x0B <- `
         '
0x0C <- `
         '

または、パイプすることができますcat -v

./binargs $'\a\b\v\f' | cat -v

これにより、結果が読みやすくなります。

argv[1]=^G^H^K^L
0x07 <- `^G'
0x08 <- `^H'
0x0B <- `^K'
0x0C <- `^L'
于 2017-02-16T14:14:07.440 に答える
0

この状況では、機能がどこにあるかを非常に意識する必要があります。処理は、プログラムを呼び出すコマンド ライン インタープリターによって行われる場合と行われない場合があります。DOS コマンド ラインを使用しているか、Linux や Unix などを使用しているかによって、同じ C コードから異なる結果が得られる場合があります。

于 2013-05-01T21:08:26.917 に答える
0

変換関数を介して C 文字列スタイルのエスケープ シーケンスを送信できることに満足している場合は、入力の途中で引用符を使用しない限り、次の方法が機能する可能性があります。入力の途中で引用符が必要な場合は、コマンド ライン引数を介して引用符を渡すためにシェルが使用するエスケープ シーケンスを把握する必要があります。

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

// Unescapes 'str' in place, collapsing it back on itself, and
// returns the resulting length of the collapsed buffer.  Handles
// mid-buffer nul characters (0x00).  You can easily add your own
// special escape sequences if you wish.  Just be sure that no escape
// sequence translates into more characters than it takes to encode
// the escape sequence itself in the original string.
int unescape(char* str)
{
    char *out, *in;
    int len=0;
    in = out = str; // both start at the same place
    while(*in)
    {
        char c = *in++;
        if (c != '\\')
            *out++ = c; // regular, unescaped character
        else
        {                   // escaped character; process it...
            c = *in++;
            if      (c == '0') *out++ = '\0';
            else if (c == 'a') *out++ = '\a';
            else if (c == 'b') *out++ = '\b';
            else if (c == 'f') *out++ = '\f';
            else if (c == 'n') *out++ = '\n';
            else if (c == 'r') *out++ = '\r';
            else if (c == 't') *out++ = '\t';
            else if (c == 'v') *out++ = '\v';
            else if (c == 'x'  // arbitrary hexadecimal value
                    && isxdigit(in[0]) && isxdigit(in[1]))
            {
                char x[3];
                x[0] = *in++;
                x[1] = *in++;
                x[3] = '\0';
                *out++ = strtol(x, NULL, 16);
            }
            else if (c>='0' && c<='3' // arbitrary octal value
                    && in[0]>='0' && in[0]<='7'
                    && in[1]>='0' && in[1]<='7')
            {
                *out++ = (c-'0')*64 + (in[0]-'0')*8 + (in[1]-'0');
                in += 2;
            }
            else // any other char following '\' is just itself.
                *out++ = *in++;
        }
        ++len; // each time through the loop adds one character
    }
    *out = '\0';
    return len;
}

void print_buf(const char* buf, int len)
{
    int col;
    unsigned char* cp = (unsigned char*)buf;
    for (col=0; len>0; --len, ++col)
        printf(" %02x%s", *cp++, ((col&16==15) ? "\n" : ""));
}

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

    if (argc<2)
    {
        fprintf(stderr, "First arg must be a string, "
                "and it probably ought to be quoted.\n");
        exit(1);
    }

    printf("\nInput string: \"%s\"\n", argv[1]);
    print_buf(argv[1], strlen(argv[1]));

    str = malloc(strlen(argv[1]));
    strcpy(str, argv[1]);
    len = unescape(str);
    printf("\nunescape() produces the following:\n");
    print_buf(str, len);
    free(str);

    printf("\n");
}
于 2013-05-01T22:55:43.823 に答える