2017-04-09 14 views
-1

私はLinux環境でいくつかのバイナリを扱っています。ユーザーの入力をスクリプト化しようとしています。例えば、最初のプログラムprog1.cで:read()syscallを使用してユーザー入力をプログラムにスクリプトする方法は?

void get_input() { 

    int i; 
    char buffer[32]; 

    i = 0; 

    while (i < 3) { 
     memset(buffer, 0, 32); 
     printf("Enter input: "); 
     fgets(buffer, 31, stdin); 
     printf("Your input: %s\n", buffer); 
     i++; 
    } 
} 

私はPROG1を実行するか、コンソールからの入力を直接入力するか、私はプログラムにスクリプトを入力し、パイプ、それをすることができます。

# ./prog1 
Enter input: Stuff1 
Your input: Stuff1 

Enter input: Stuff2 
Your input: Stuff2 

Enter input: Stuff3 
Your input: Stuff3 

# 

スクリプト入力:コンソールから直接入力を行う

# perl -e 'print "Stuff1\n" . "Stuff2\n" . "Stuff3\n"' | ./prog1 
Enter input: Your input: Stuff1 

Enter input: Your input: Stuff2 

Enter input: Your input: Stuff3 

# 

を出力のフォーマットが少し台無しにしているが、プログラムは依然として期待出力を表示します。

私の問題は、二進prog2.cである:私は、コンソールから直接、私の入力を入力することができた場合

# ./prog2 
Stuff1 
Enter input: Your input: Stuff1 

Stuff2 
Enter input: Your input: Stuff2 

Stuff3 
Enter input: Your input: Stuff3 

# 

が入力を入力するプロンプトが表示されないだけでなく、私が入力を入力するまで、私は入力をスクリプトすることはできません:

# perl -e 'print "Stuff1\n" . "Stuff2\n" . "Stuff3\n"' | ./prog2 
Enter input: Your input: Stuff1 
Stuff2 
Stuff3 

Enter input: Your input: 
Enter input: Your input: 
# 

私はいくつかの研究を行ったfgets()read()と発見の間ifferences:

  1. fgets()read()がシステムコールであるのに対し、C関数です。
  2. fgets()は改行文字またはEOFが検出されるまで入力を読み取りますが、改行はread()システムコールと同じ効果を持ちません。
  3. read()は、fgets()のような何らかのバッファリングメカニズムを採用しています。

私はポイント2と3が手元の問題に最も関連していると思っていますが、私の問題を解決する方法を私には示唆していません。

これらのプログラムを提供する必要があるユーザー入力には、印刷不可能な16進バイトが含まれているため、コンソールから直接入力するのは不十分です。また、ソースコードをバイナリに変更することもできませんので、fgets()を使用して入力を収集する回避策はありません。

私の質問は、prog1と同じ動作をするようにprog2に入力を与える方法があるかどうかです。

ありがとうございます。

+0

質問デバッグヘルプ(「なぜこのコードは機能していませんか?」)には、目的の動作、特定の問題またはエラー、および質問自体に再現するのに必要な最短コードが含まれている必要があります。明確な問題文がない質問は、他の読者にとって有用ではありません。参照:最小、完全、および検証可能な例を作成する方法。 – Olaf

+0

関数 'fgets()'は、入力の終わりにNUL( '\ 0')バイトを置くための関数のために利用可能な 'スペア'バイトが存在する間、バイトの入力を止めるのに十分スマートです。したがって、バッファの長さのパラメータは、バッファの実際の長さである必要があります – user3629249

+0

質問は完全に変更されました。 –

答えて

0
を使用

この問題の回避策が見つかりました。私はバイナリとやりとりすることができません。私はコンソールから入力をスクリプト化していますが、プログラムでそれを行う方法を見つけました。

私はsubprocessモジュールのラッパーとして機能Pythonライブラリ・スイートを使用していますが、あなたは、単に書くことができ、あなた自身:これはプロセスとしてバイナリを開き、その後、することができます

p = subprocess.Popen(prog2, stdout=subprocess.PIPE, stdin=subprocess.PIPE) 

Pythonスクリプト内から関数を送受信することでそれと対話します。

これは、これが似たような問題に遭遇した他の誰にも役立つことを願っています。

3

read(2)バッファレスではなく、fgets/printf/etcから<stdio.h>にすると、パフォーマンスが向上します。

行を読むには、fgetsを付けます。しかし、印刷不可能なデータ(バイナリ)のブロックを読み取る場合は、freadを使用してください。そしてどんな場合でも、戻り値をチェックしてください。

+0

デバッグ時に、私はgdbで自分の入力をスクリプト化するときに以下を見つけました。これは、読み取り後のレジスタの状態()を呼び出すです: EAX:0x15の ECX:私は出力から、しかし、それはdoesnのことを思いました可能性があり 0xbffff60c( "Stuff1 \ nStuff2 \ nStuff3 \ nを")回避策を見つけるのを助けてください。 –

1

'バイナリ' ファイルを読み込む(ETC、NULバイトを含むことができる)を使用する '(読み取り)' または 'のfread()'

テキストファイルを読み取り、 'のfgets()'

+0

私は同意しますが、元の質問に記載されているように、私はソースを変更するオプションがないので、私は自分が持っているもので作業する必要があります。 –

関連する問題