Pregunta sobre std, c++, boost, boost-iostreams – ¿Cómo leer un archivo en una matriz de caracteres sin firmar desde std :: ifstream?

4

Así que normalmente hago cosas como:

<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>

Me pregunto cómo leer enunsigned char buffer (boost::shared_array<unsigned char> buffer( new unsigned char[buff_length]);)

Además, prefiero un shared_ptr <std :: vector <uint8_t>> a shared_array Viktor Sehr
Uno de los casos dondereinterpret_cast<> Es en realidad el enfoque correcto. Chad

Tu respuesta

1   la respuesta
11

En una forma más simple:

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

Reemplazarstd::cin con su corriente real.

Es probable que lo anterior haga más de una asignación de memoria (para archivos de más de unos pocos bytes) porquestd::istreambuf_iterator<> es un iterador de entrada, no un acceso aleatorio o un iterador directo, por lo que la longitud del archivo no se puede medir restando iteradores comoend - begin o llamandostd::distance(begin, end). Se puede reducir a una asignación de memoria si el vector se crea primero vacío, luegostd::vector<>::reserve() se llama para asignar memoria para la longitud del archivo y finalmente se llama inserción de rangovec.insert(vec.end(), beg, end) conbeg yend siendostd::istreambuf_iterator<> como arriba para leer todo el archivo.

Si el tamaño del archivo es superior a unos pocos kilo-bytes, puede ser más eficiente asignarlo a la memoria del proceso para evitar copiar la memoria desde el kernel al espacio del usuario.

La razónstd::istreambuf_iterator<char> Se utiliza es porque la implementación utilizastd::char_traits<> que normalmente tiene especializaciones sólo parachar ywchar_t. Independientemente, los estándares C y C ++ requieren todoschar tipos para tener el mismo diseño binario sin bits de relleno, por lo que las conversiones entrechar, unsigned char ysigned char (que son todos los tipos distintos, a diferencia designed int yint siendo el mismo tipo) conservan patrones de bits y por lo tanto son seguros.

[basic.fundamental / 1]

Llanurachar, signed charyunsigned char Son tres tipos distintos, llamados colectivamentetipos de caracteres estrechos. UNAchar, unasigned char, y ununsigned char ocupan la misma cantidad de almacenamiento y tienen los mismos requisitos de alineación; es decir, tienen la misma representación de objeto ... Para los tipos de caracteres estrechos, todos los bits de la representación de objetos participan en la representación del valor ... Para los tipos de caracteres estrechos sin signo, cada patrón de bits posible de la representación del valor representa un número distinto. Estos requisitos no son válidos para otros tipos. En cualquier implementación particular, un planochar objeto puede tomar ya sea los mismos valores que unasigned char o ununsigned char; cuál es la implementación definida. Para cada valori de tipounsigned char en el rango de 0 a 255 inclusive, existe un valorj de tipochar de tal manera que el resultado de una conversión integral dei achar esj, y el resultado de una conversión integral dej aunsigned char esi.

@MaximEgorushkin ese texto (agregado en C ++ 14) parece requerir quesi está firmado el llano Debe seguir el complemento a 2. Pero en primer lugar, no hay un requisito equivalente en C como reclamas, y en segundo lugar, todavía permitesigned char c = -1; para usar el complemento de uno (es decir, obtener el patrón de bits 11111110) y tener el carácter simple sin signo M.M
@ M.M Agregué una cita más larga para ti.Representación del valor Es diferente (el bit de signo).Representación de objetos es el mismo. Maxim Egorushkin
Los estándares no requieren quechar c = -1; unsigned char u = c; resultados enc yu teniendo el mismo patrón de bits. En teoría, los caracteres con signo podrían usar el complemento de 1 o la magnitud de signo. M.M
+1 para el último párrafo sehe

Preguntas relacionadas