Вопрос по c++ – Как прочитать файл в массив без знака из std :: ifstream?

4

Так что обычно я делаю такие вещи, как:

<code>    std::ifstream stream;
    int buff_length = 8192;
    boost::shared_array<char> buffer( new char[buff_length]);
    stream.open( path.string().c_str(), std::ios_base::binary);
    while (stream)
    {
            stream.read(buffer.get(), buff_length);
            //boost::asio::write(*socket, boost::asio::buffer(buffer.get(), stream.gcount()));
    }
    stream.close();
</code>

Интересно, как читать вunsigned char буфер (boost::shared_array<unsigned char> buffer( new unsigned char[buff_length]);)

Кроме того, я бы предпочел shared_ptr & lt; std :: vector & lt; uint8_t & gt; & gt; к shared_array Viktor Sehr
Один из случаев, когдаreinterpret_cast<> на самом деле правильный подход. Chad

Ваш Ответ

1   ответ
11

В простейшей форме:

std::vector<unsigned char> vec(
      std::istreambuf_iterator<char>(std::cin)
    , std::istreambuf_iterator<char>()
    );

замещатьstd::cin с вашим реальным потоком.

Выше, вероятно, будет делать больше, чем одно выделение памяти (для файлов, размер которых превышает несколько байтов), потому чтоstd::istreambuf_iterator<> является итератором ввода, а не итератором с произвольным доступом или прямым, так что длина файла не может быть измерена путем вычитания итераторов, таких какend - begin или звонитstd::distance(begin, end), Он может быть уменьшен до одного выделения памяти, если вектор создается сначала пустым, затемstd::vector<>::reserve() вызывается для выделения памяти для длины файла и, наконец, вызывается вставка диапазонаvec.insert(vec.end(), beg, end) сbeg а такжеend являющийсяstd::istreambuf_iterator<> как выше, чтобы прочитать весь файл.

Если размер файла превышает несколько килобайт, может быть наиболее эффективно отобразить его в памяти процесса, чтобы избежать копирования памяти из ядра в пространство пользователя.

Причинаstd::istreambuf_iterator<char> используется потому, что реализация используетstd::char_traits<> который обычно имеет специализации только дляchar а такжеwchar_t, Несмотря на это, стандарты C и C ++ требуют всеchar типы имеют одинаковую двоичную разметку без битов заполнения, поэтому преобразования междуchar, unsigned char а такжеsigned char (которые являются разными типами, в отличие отsigned int а такжеint будучи однотипными) сохраняют битовые комбинации и, следовательно, являются безопасными.

[Basic.fundamental / 1]

Plain char, signed char, and unsigned char are three distinct types, collectively called narrow character types. A char, a signed char, and an unsigned char occupy the same amount of storage and have the same alignment requirements; that is, they have the same object representation... For narrow character types, all bits of the object representation participate in the value representation... For unsigned narrow character types, each possible bit pattern of the value representation represents a distinct number. These requirements do not hold for other types. In any particular implementation, a plain char object can take on either the same values as a signed char or an unsigned char; which one is implementation-defined. For each value i of type unsigned char in the range 0 to 255 inclusive, there exists a value j of type char such that the result of an integral conversion from i to char is j, and the result of an integral conversion from j to unsigned char is i.

Стандарты не требуют, чтобыchar c = -1; unsigned char u = c; результаты вc а такжеu имея тот же битовый шаблон. Теоретически, подписанные символы могут использовать 1 дополнение или значение знака.
+1 за последний абзац
Они явно не имеют одинакового представления значения; Значение-1 действительно имеет представление значения вsigned char но не вunsigned char
Non-negative Значения знакового символа должны иметь то же представление, что и соответствующий неподписанный символ. Но в одном дополнении, например,char c = -1; имеет битовый паттерн 11111110, тогда какunsigned char u = c; имеет битовый паттерн 11111111. Это в основном академично, так как я не знаю ни одной реализации C ++, которая когда-либо не использовала дополнение 2.
@ M.M Добавил цитату для вас.

Похожие вопросы