2017-04-04 36 views
0

私は基本的にはマスターブートレコードからパーティションテーブル情報を取得して構文解析するためにsudo dd if=/dev/sda ibs=1 count=64 skip=446コマンドを使用しようとしています。それを解析するために文字列に出力しますが、私が得るのは次のとおりです:� !。私は何を期待してることは次のとおりです。C++プログラムのLinux 'dd'コマンドの出力に問題がある

80 01 01 00 83 FE 3F 01 3F 00 00 00 43 7D 00 00 00 00 01 02 83 FE 3F 0D 82 7D 00 00 0C F1 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

私の現在のコードは次のようになり、そしてちょうどここから取られる:How to execute a command and get output of command within C++ using POSIX?

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

using namespace std; 

string exec(const char* cmd) { 
    char buffer[128]; 
    string result = ""; 
    FILE* pipe = popen(cmd, "r"); 
    if (!pipe) throw std::runtime_error("popen() failed!"); 
    try { 
     while (!feof(pipe)) { 
      if (fgets(buffer, 128, pipe) != NULL) 
       result += buffer; 
     } 
    } catch (...) { 
     pclose(pipe); 
     throw; 
    } 
    pclose(pipe); 
    return result; 
} 

int main() { 

    string s = exec("sudo dd if=/dev/sda ibs=1 count=64 skip=446"); 
    cout << s; 

} 

明らかに「私は何か間違ったことをやってんだけど、私ができます問題を解明するどのように私の文字列に適切な出力を得るのですか?

+0

ところで、あなたは[なぜ、while(!feof(file))が常に間違っているのですか?](http://stackoverflow.com/questions/5431941/why-is-while-feof-file -always-wrong) – molbdnilo

+1

コマンドラインからコマンドを実行すると、期待どおりの出力が得られますか?コマンドは生のバイナリデータをダンプするだけなので、私は真剣に疑っています。生のバイナリデータはテキストのように扱うことができません。 –

+0

また、なぜ読み込みループを 'try-catch'に入れていますか?例外を引き起こす可能性があるのは、文字列に追加するときにメモリ不足が発生した場合だけです。それでも、プログラムの終了はパイプを閉じてしまい、実用的な必要はありません。 –

答えて

0
while (!feof(pipe)) { 

これはyour first bugです。

result += buffer; 

これは2番目のバグです。 buffercharの配列であり、このコンテキストではchar *に減衰します。ご存じのように、文字列コンテキストのchar *は、通常、 '\0'バイトで終了するCスタイルの文字列として解釈されます。

00バイトの読み込みが予想されることがあります。さて、char配列がchar *に崩壊した後、最初の00バイトまでのすべてが正確に128バイトではなくresultに追加されます。また、128バイトに00バイトがない場合は、クラッシュの可能性が低いランダムなゴミが追加ボーナスとして追加される可能性があります。

if (fgets(buffer, 128, pipe) != NULL) 

これは3番目のバグです。読み取られたデータに0Aバイト('\n'文字)が含まれている場合、128バイトは読み取られません。

cout << s; 

これは4番目のバグです。データはバイナリのものを含んでいる可能性があるので、おそらくバイト00から1Fまでのバイトを表示することができます。

  1. が正しくファイル終了条件を扱う:

    が必要になりますあなたのコードを修正します。

  2. バイナリデータを正しく読み取ります。 fgets()、などは、このタスクには完全に不適切です。 Cファイル構造の使用を主張する場合は、妥当な唯一のオプションはfread()です。

  3. バイナリデータの集まりからstd::stringを正しくアセンブルします。 charというバッファーを追加するだけで、指を交差させ、最高の状態を望むなら動作しません。 2つの引数のstd::stringコンストラクタを使用する必要があります。コンストラクタは、パラメータとして開始イテレータ値と終了イテレータ値を取ります。

  4. ブロブ全体をstd::coutにダンプするのではなく、正しくバイナリデータを表示します。最も一般的なアプローチは、std::hexマニピュレータであり、それぞれcharint,に慎重にアップコンバートし、符号なし値とします。

関連する問題