# vectorchar to int

This topic is 4950 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Alright, again this feels like a stupid question but I can't think of the right way to do it. I've got a vector<char> buffer, and I'm reading binary data into it from a file. This data is structured, some of it consisting of bytes, but other parts consisting of words and dwords. Whats the best way to read an int out of a particular point in this vector? For example:
vector<char> buffer;
unsigned int stringsize;

// file is read into the buffer here...

stringsize = buffer[28];

I know the last line is incorrect, but thats the sort of idea I'm trying to get at, I'm sure there's a better way to do it than something like this:
stringsize = (buffer[29] << 8) | buffer[28];


##### Share on other sites
This should work for basic types on an x86, but don't assume it to be portable:

template<typename Type>const std::vector<char>& operator>>(const std::vector<char>& buf, Type& out){    out = (Type*)&vector.at(offset);    return buf;}void test(){    std::vector<char> buffer;    // fill the buffer    int value;    buffer >> value;}

##### Share on other sites
Hmm. That seems almost as bad as doing it manually. And portability is a pretty high priority. Pointers are a definite option, since vectors are contiguous I could use it as a char array and interpret it as anything, but I was hoping to avoid that.

Also, pulling an int out of the vector was just one case, there are several other data types I need to pull out, such as strings (preferably std::string).

One option was to read it as a struct vector instead of char vector, but the data contains variable-length text strings, which makes that just as complex.

I suppose I could always do something like:

vector<char> buffer;int *data = &buffer[28];int value = *data;

But it seems very round-about. Is there no standard way of doing this?

##### Share on other sites
I would suggest that you fill the appropriate variables when reading in your file, instead of reading it all to a vector and then trying to parse the vector.

You might also want to look at the section on settings in the Enginuity series here, if you don't like the previous suggestion.
 What is it you are trying to do, exactly, before I send you in the wrong direction?

Note: joanusdmentia's code seems like it confuses istream and vector; it needs offset defined. Also, vector.at should read buf.at

Regards,
jflanglois

[Edited by - jflanglois on December 4, 2004 9:50:32 PM]

##### Share on other sites
Reading individual values might be the best idea, I was just trying to minimize disk access.

What I'm doing right now is parsing zip files, reading the tables to locate the compressed file headers and read out the file info and names.

##### Share on other sites
Quote:
 Original post by NairouReading individual values might be the best idea, I was just trying to minimize disk access.

Don't try (not in this way, anyway); the stream object does this for you (by reading a "page" of the file at a time and maintaining an internal buffer).

##### Share on other sites
What are you using to read you file? ifstream? CreateFile? fopen?
With ifstream, it would look like this:

#include <iostream>#include <fstream>using namespace std;int main() {  ifstream fin( "test.zip", ios::binary );  // Find the number of files in this record  fin.seekg( -22, ios_base::end );  // Find the begining of the central directory of this record  unsigned sig;  fin.read( reinterpret_cast < char * > ( &sig ), 4 );  while ( sig != 0x06054b50 ) {    fin.seekg( -5, ios_base::cur );    fin.read( reinterpret_cast < char * > ( &sig ), 4 );  }  // go to number of files  fin.seekg( 6, ios_base::cur );  // get number of files  short numfiles;  fin.read( reinterpret_cast < char * > ( &numfiles ), sizeof( numfiles ) );  // get length of name of first element  fin.seekg( 26 );  short strlength;  fin.read( reinterpret_cast < char * > ( &strlength ), sizeof( strlength ) );  // get name of first element  char *filename = new char[strlength + 1];  fin.seekg( 2, ios_base::cur );  fin.read( filename, strlength );  filename[strlength] = '\0';  cout << "First file: \"" << filename << "\"" << endl;  delete [] filename;  cin.get();  return 0;}

Output:
Quote:
 First file: "sorcerers.txt"

What spec are you using?

##### Share on other sites
Quote:
Original post by Zahlman
Quote:
 Original post by NairouReading individual values might be the best idea, I was just trying to minimize disk access.

Don't try (not in this way, anyway); the stream object does this for you (by reading a "page" of the file at a time and maintaining an internal buffer).

I don't understand what you mean by this. The ifstream will keep a cursor on the file. How does that mean that it is not a good idea to read individual values from the file instead of the whole file to a buffer, and then trying to parse that?

##### Share on other sites
Thanks jflanglois, that clears it up a lot. I'm using ifstream (via boost::filesystem), I just didn't want to assume the read calls were being buffered in advance. :)

I'm using the PKZip specs off the pkware site, and its all working well now. I went ahead and have it reading the bulk of the header directly into a struct now, then directly reading the variable parts (like filenames) as I need them afterwards.

##### Share on other sites
You're welcome. That's the spec I used as well. Make sure you don't read the central directory for file headers because according to the site the CD can be compressed (unless of course you have code to decompress it).

1. 1
2. 2
Rutin
19
3. 3
4. 4
5. 5

• 14
• 12
• 9
• 12
• 37
• ### Forum Statistics

• Total Topics
631434
• Total Posts
3000050
×

## Important Information

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!