exec — Не удается получить вывод команды Linux ‘dd’ в программе на C ++

Я пытаюсь использовать sudo dd if=/dev/sda ibs=1 count=64 skip=446 Команда для получения информации таблицы разделов из основной загрузочной записи для ее анализа Я в основном пытаюсь прочитать вывод в строку, чтобы проанализировать ее, но все, что я получаю, это следующее: � !, Я ожидаю, что это:

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

Мой текущий код выглядит следующим образом, и просто взят отсюда: Как выполнить команду и получить вывод команды в C ++, используя 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(pipe)) {

Это твоя первая ошибка.

result += buffer;

Это твоя вторая ошибка. buffer это char массив, который распадается на char * в данном контексте. Как вы знаете, char * в контексте строки обычно интерпретируется как строка в стиле C, оканчивающаяся на ‘\0‘байт.

Вы могли заметить, что вы ожидаете получить кучу 00 прочитано байтов. Ну, после char массив распадается на char *, все до первого 00 байт будет добавлен к вашему result, а не 128 байтов, точно. И если бы не было 00 байтов в этих 128 байтах, вы, вероятно, в конечном итоге получите некоторый случайный мусор в качестве дополнительного бонуса с небольшой вероятностью сбоя.

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

Это ваш третий баг. Если прочитанные данные включают в себя 0A байт '\n' символ, это не будет читать 128 байтов.

cout << s;

Это ваша четвертая ошибка. Поскольку данные будут (после того, как все другие ошибки исправлены) предположительно содержат двоичные данные, ваш терминал вряд ли будет иметь большой успех, отображая различные байты, особенно байты 00 через 1F,

Для исправления вашего кода вам необходимо:

  1. Правильно обрабатывать условие конца файла.

  2. Правильно читать двоичные данные. fgets()и др. совершенно не подходят для этой задачи. Если вы настаиваете на использовании файловых структур C, единственным разумным вариантом является использование fread(),

  3. Правильно собрать std::string из двоичного объекта двоичных данных. Просто добавив char Буфер к нему, скрестив пальцы и надеясь на лучшее, не сработает. Скорее всего, вам нужно будет использовать два аргумента std::string конструктор, который принимает начальное и конечное значение итератора в качестве параметров.

  4. Правильно отображать двоичные данные, а не просто выводить весь двоичный объект в std::cout, Просто так. Наиболее распространенным подходом является std::hex манипулятор, и прилежное преобразование каждого char для int, в качестве значения без знака.

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector