C ++, запись вектора <char>в ofstream пропускает пробелы - PullRequest
3 голосов
/ 16 февраля 2012

Несмотря на мои искренние усилия, я не могу найти ошибку здесь. Я пишу вектор в офстрим. Вектор содержит двоичные данные. Однако по какой-то причине, когда символ пробела (0x10, 0x11, 0x12, 0x13, 0x20) должен быть записан, он пропускается.

Я пытался использовать итераторы и прямой ofstream :: write ().

Вот код, который я использую. Я закомментировал некоторые другие методы, которые я пробовал.

void
write_file(const std::string& file,
           std::vector<uint8_t>& v)
{
  std::ofstream out(file, std::ios::binary | std::ios::ate);

  if (!out.is_open())
    throw file_error(file, "unable to open");

  out.unsetf(std::ios::skipws);

  /* ostreambuf_iterator ...
  std::ostreambuf_iterator<char> out_i(out);
  std::copy(v.begin(), v.end(), out_i);
  */

  /* ostream_iterator ...
  std::copy(v.begin(), v.end(), std::ostream_iterator<char>(out, ""));
  */

  out.write((const char*) &v[0], v.size());
}

РЕДАКТИРОВАТЬ: И код, чтобы прочитать его обратно.

void
read_file(const std::string& file,
          std::vector<uint8_t>& v)
{
  std::ifstream in(file);
  v.clear();

  if (!in.is_open())
    throw file_error(file, "unable to open");

  in.unsetf(std::ios::skipws);

  std::copy(std::istream_iterator<char>(in), std::istream_iterator<char>(),
      std::back_inserter(v));
}

Вот пример ввода:

30 0 0 0 a 30 0 0 0 7a 70 30 0 0 0 32 73 30 0 0 0 2 71 30 0 0 4 d2

И это вывод, который я получаю, когда читаю его обратно:

30 0 0 0 30 0 0 0 7a 70 30 0 0 0 32 73 30 0 0 0 2 71 30 0 0 4 d2

Как видите, 0x0a опущено, якобы потому, что это пробел.

Любые предложения будут с благодарностью.

Ответы [ 4 ]

1 голос
/ 16 февраля 2012

Вы забыли открыть файл в двоичном режиме в функции read_file.

1 голос
/ 16 февраля 2012

Вместо того, чтобы возиться с записью вектора <> s, boost::serialization - более эффективный способ, использующий boost::archive::binary_oarchive.

0 голосов
/ 24 февраля 2014

Конструктор istream_iterator пропускает пробелы. Попробуйте заменить ваш std :: copy следующим:

std::copy(
    std::istreambuf_iterator<char>(in),
    std::istreambuf_iterator<char>(),
    std::back_inserter(v));

istreambuf_iterator напрямую переходит к объекту streambuf, что позволяет избежать обработки пробелов, которую вы видите.

0 голосов
/ 16 февраля 2012

Я думаю, что «а» рассматривается как новая строка.Я все еще должен думать, как обойти это.

...