سؤال

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!

هل كانت مفيدة؟

المحلول

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;

نصائح أخرى

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] );
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top