Domanda

Sto cercando di leggere un file BMP con fstream. Tuttavia salta i valori compresi tra 08 e 0E (hex) per esempio, per valori 42 4d 8a 16 0b 00 00 00 00 00 36

si legge

42 4d 8a 16 00 00 00 00 00 36

saltare 0b come non esiste nemmeno nel documento.

Cosa fare?

codice:

ifstream in;
in.open("ben.bmp", ios::binary);
unsigned char a='\0';
ofstream f("s.txt");
while(!in.eof())
{
    in>>a;
    f<<a;
}

EDIT: usando al posto del in.read(a,1); in>>a; risolve il problema di lettura, ma ho bisogno di scrivere caratteri non firmati e f.write(a,1); non accetta i caratteri non firmati. Qualcuno ha una funzione per fare la scrittura con caratteri non firmati?

È stato utile?

Soluzione

#include <fstream>
#include <iostream>
#include <string>

int main(int argc, char *argv[])
{
  const char *bitmap;
  const char *output = "s.txt";

  if (argc < 2)
    bitmap = "ben.bmp";
  else
    bitmap = argv[1];

  std::ifstream  in(bitmap, std::ios::in  | std::ios::binary);
  std::ofstream out(output, std::ios::out | std::ios::binary);
  char a;

  while (in.read(&a, 1) && out.write(&a, 1))
    ;

  if (!in.eof() && in.fail())
    std::cerr << "Error reading from " << bitmap << std::endl;

  if (!out)
    std::cerr << "Error writing to "   << output << std::endl;

  return 0;
}

Altri suggerimenti

Se si desidera leggere il file di un byte alla volta questo è un buon uso per l'iteratore buffer di istream.

int main()
{
   ifstream in("ben.bmp", ios::binary);  
   ofstream f("s.txt");  

   //
   // Note: this is NOT istream_iterator
   // The major different is that the istreambuf_iterator does not skip white space.
   //
   std::istreambuf_iterator<char>  loop(in);
   std::istreambuf_iterator<char>  end;

   for(; loop != end; ++loop)
   {
       f << (*loop);  
   }

   // You could now also use it with any of the std algorithms
       // Alternative to Copy input to output
            std::copy(loop,end,std::ostream_iterator<char>(f));

       // Alternative if you want to do some processing on each element
       // The HighGain_FrequencyIvertModulator is a functor that will manipulate each char.
            std::transform( loop,
                            end,
                            std::ostream_iterator<char>(f),
                            HighGain_FrequencyIvertModulator()
                          );
}  

Il operator>> e operator<< sono progettati per l'input e l'output testuale.

Per usare i file binari read() e write().

Diverse questioni:

while(!in.eof())
{
    in>>a;
    f<<a;
}

Non è questo il modo giusto di leggere un file - è necessario controllare se la lettura ha funzionato:

while( in >> a)
{
    f<<a;
}

In secondo luogo, se si vuole leggere un file in modalità binaria, è necessario utilizzare il read () e le funzioni correlate - l'operatore >> effettuerà sempre formattato (non binario) in ingresso, non importa quale sia la modalità del file è aperto nel.

Modifica scrittura avrà bisogno di un cast:

unsigned char c = 42;
out.write( (char *) & c, 1 );

Questo perché il flusso è interpretare i byte come caratteri ASCII. 08 attraverso 0e sono spazi bianchi (tab orizzontale, capo, tabulazioni verticale, ritorno del carrello, ecc), che vengono saltato. Come le altre risposte hanno detto, è necessario utilizzare il metodo read () del flusso.

Quando si tratta di dati binari, utilizzare read () in contrasto con gli operatori bit a bit sovraccarico (<< e >>)

Se avete bisogno di utilizzare i flussi, è possibile fare qualcosa di simile:

std::ifstream ifs("bar", std::ios::in | std::ios::binary);
std::ofstream ofs("foo", std::ios::out | std::ios::binary);
ofs << ifs.rdbuf();

Assicurati lo si apre come un file binario in questo modo:

ifstream ifs('input.bin', ios::in | ios::binary);

ofstream ofs('output.bin', ios::out | ios::binary);

è anche una buona pratica per verificare ifs.good() per assicurarsi che tutto è ok con il file aperto

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top