Pergunta sobre boost-iostreams, boost, std, c++ – Como ler um arquivo em matriz de caracteres não assinados de std :: ifstream?

4

Então normalmente eu faço coisas 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>

Eu me pergunto como lerunsigned char amortecedor (boost::shared_array<unsigned char> buffer( new unsigned char[buff_length]);)

Um dos casos em quereinterpret_cast<> é na verdade a abordagem correta. Chad
Além disso, eu preferiria um shared_ptr <std :: vector <uint8_t >> para shared_array Viktor Sehr

Sua resposta

1   a resposta
11

De uma forma mais simples:

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

Substituirstd::cin com seu fluxo real.

É provável que o acima faça mais de uma alocação de memória (para arquivos maiores que uns poucos bytes) porquestd::istreambuf_iterator<> é um input-iterator, não um acesso aleatório ou um iterador forward, então o tamanho do arquivo não pode ser medido subtraindo iteradores comoend - begin ou chamandostd::distance(begin, end). Pode ser reduzido para uma alocação de memória se o vetor for criado primeiro vazio e depoisstd::vector<>::reserve() é chamado para alocar memória para o tamanho do arquivo e, finalmente, inserir intervalo é chamadovec.insert(vec.end(), beg, end) combeg eend serstd::istreambuf_iterator<> como acima para ler o arquivo inteiro.

Se o tamanho do arquivo for maior que alguns quilo bytes, pode ser mais eficiente mapeá-lo na memória do processo para evitar a cópia da memória do kernel para o espaço do usuário.

O motivostd::istreambuf_iterator<char> é usado porque a implementação usastd::char_traits<> que normalmente tem especializações apenas parachar ewchar_t. Independentemente disso, os padrões C e C ++ exigemchar tipos para ter o mesmo layout binário sem bits de preenchimento, então conversões entrechar, unsigned char esigned char (que são todos tipos distintos, diferentementesigned int eint sendo o mesmo tipo) preservar padrões de bits e, portanto, são seguros.

[basic.fundamental / 1]

Aviãochar, signed chareunsigned char são três tipos distintos, chamados coletivamentetipos de caracteres estreitos. UMAchar, umasigned char, e umunsigned char ocupar a mesma quantidade de armazenamento e ter os mesmos requisitos de alinhamento; ou seja, eles têm a mesma representação de objeto ... Para tipos de caracteres estreitos, todos os bits da representação de objeto participam da representação de valor ... Para tipos de caractere estreitos não assinados, cada padrão de bit possível da representação de valor representa um número distinto. Esses requisitos não são válidos para outros tipos. Em qualquer implementação particular, uma planíciechar objeto pode assumir os mesmos valores como umsigned char ou umunsigned char; qual é definido pela implementação. Para cada valori do tipounsigned char no intervalo de 0 a 255, existe um valorj do tipochar tal que o resultado de uma conversão integral dei parachar éj, e o resultado de uma conversão integral dej paraunsigned char éi.

@ M.M Adicionado uma cotação mais longa para você.Representação de valor é diferente (o bit de sinal).Representação de objetos é o mesmo. Maxim Egorushkin
+1 para o último parágrafo sehe
@ MaximEgorushkin esse texto (adicionado em C + + 14) parece exigir quese o caractere simples estiver assinado deve seguir o complemento de 2. Mas em primeiro lugar, não há exigência equivalente em C, como você afirma, e em segundo lugar, ainda permitesigned char c = -1; para usar um complemento (ou seja, obter padrão de bits 11111110) e ter caracteres simples não assinados M.M
Os padrões não exigem quechar c = -1; unsigned char u = c; resulta emc eu tendo o mesmo padrão de bits. Em teoria, os caracteres assinados poderiam usar o complemento de 1 ou o sinal de magnitude. M.M

Perguntas relacionadas