Question

I am currently writing an iOS app with a client-server architecture (TCP communication). I am now writing a module on the server side which is supposed to read a sound file as hex values, and send the sound file 1024 by 1024 bytes to the client.

I am not an experienced C++ developer, and I need some help with my file reading. Right now my code is:

void PacketInterpreter::sendFile(int turn, int gameID){
    std::string absoluteFilePath = (std::to_string(gameID) + "/sound.caf");
    unsigned char x;

    std::ifstream file(absoluteFilePath, std::ios::binary);
    file >> std::noskipws;

    std::string outstream;

    while(file >> x){
        outstream << std::hex << (int)x;
    }
}

I am getting the

Invalid operands to binary expression ('std::string' (aka 'basic_string, allocator >') and 'std::__1::ios_base &(std::__1::ios_base &)')

error right now, and I figure out as much as that's the compiler complaining because it does not want to read in byte by byte into the std::string. Why, however, I don't know.

I'd be very happy if you could help me find a better way to do this. I'd love some input on how to split the file into 1024byte chunks as well. Thanks in advance!

Était-ce utile?

La solution

Don't use the formatted stream insertion (<<) or extraction (>>) operators with binary files.

Instead, use the istream::read or ostream::write methods.

Edit 1: Example of block reading.

#define BUFFER_CAPACITY 512
unsigned char buffer[BUFFER_CAPACITY];
ifstream input_data("my_data.caf");
input_data.read((unsigned char)&buffer[0], sizeof(buffer));
//...
cout << "Look, first by is "
     << "0x" << hex << buffer[0]
     << " or as decimal: " << dec << buffer[0]
     << endl;

Autres conseils

As OP also asked for reading in 1K blocks and wanting to warn against a simple hex which will not produce pairs of hex digits, here is a more comprehensive draft for a solution. Error handling is sketchy, but shouldn't be omitted.

#include <fstream>
#include <iostream>
#include <iomanip>

void process( char* buffer, size_t len ){
  for( int i = 0; i < len; i++ ){
    std::cout << std::setbase( 16 ) << std::setw( 2 ) << std::setfill( '0' )
              << (unsigned)buffer[i];
  }
}

void sendfile( char * pathname ){
  std::ifstream ifs( pathname, std::ifstream::in );
  if( ifs.fail() ) throw "error opening";

  const std::size_t BUFFER_SIZE = 1024;
  char buffer [BUFFER_SIZE];

  size_t nRead = 0;
  while( ifs.read (buffer, sizeof(buffer)) ){
    process( buffer, ifs.gcount() );
  }
  if( ! ifs.eof() ) throw "error reading";

  process( buffer, ifs.gcount() );
  ifs.close();
}

int main( int argc, char* args[] ){
  if( 0 == argc ) throw "missing argument";
  sendfile( args[1] );
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top