Sign in to follow this  
zix99

Reading data from a char array

Recommended Posts

zix99    205
Hi all, thank for all your help (again), seems like i'm almost asking to much In C++ you can read information from a FILE*, once you open it using fread(). I was wondering if there is a similiar command to read data from a unsigned char *buffer. The reason why I want to do this, is i want to load a file, decompress it, and read information right from this, instead of having to resave the file to the disk, and then reading from the file. The file is 15 megs uncompressed, and needs to be decompressed and read quickly in real time. Is there any way to do this? Thanks in advance ~zix~

Share this post


Link to post
Share on other sites
MindWipe    940
for a char array you do:

unsigned char *buffer;

//Load or create buffer here

unsigned char firstUCHAR = buffer[0];
unsigned char secondUCHAR = buffer[1];

unsigned char chars[32];

for(int i = 0; i < 32; i++) chars[i] = buffer[i];

Or you can do it like this

unsigned char *bp = buffer;

unsigned char firstUCHAR = *bp;
unsigned char secondUCHAR = *(bp + 1);



EDIT: Or do you want to read the file like you read a uchar array?

/MindWipe

Share this post


Link to post
Share on other sites
Zahlman    1682
In general, stdio operations that start with 'f' and operate on files, have equivalents that start with 's' and operate on strings. Hence sscanf, for example. However, there is no 'sread' or 'swrite' largely because of the binary (as opposed to text) nature of those operations; since they work with raw bytes, the expectation is that you do equivalent things with strings by just doing pointer arithmetic (or its higher-level cousin, array indexing).

(The reasons you can't just do pointer arithmetic on a FILE * are presumably (a) it's likely a typedef for some structure that hides indirection from you, such that you'd be writing to the wrong place; (b) files aren't random-access in the same way that memory is, so pointer arithmetic allows operations that can't cleanly be implemented.)

Anyway... in C++, you should consider reading text data using the stream extraction '>>' operator, and binary data by... I forgot the exact details, but there is a nice way with the STL to dump a file into a vector<char> ... someone want to provide it? :)

Share this post


Link to post
Share on other sites
SiCrane    11839
Quote:
Original post by Zahlman
Anyway... in C++, you should consider reading text data using the stream extraction '>>' operator, and binary data by... I forgot the exact details, but there is a nice way with the STL to dump a file into a vector<char> ... someone want to provide it? :)


Sure:

#include <vector>
#include <fstream>
#include <iterator>

int main(int, char **) {
std::ifstream ifs("temp.cpp");

std::vector<char> vector_with_files_contents( (std::istreambuf_iterator<char>(ifs)),
(std::istreambuf_iterator<char>()) );
return 0;
}


But why is this relevant?

Share this post


Link to post
Share on other sites
zix99    205
Hey all, thanks for the reply.. sorry it took me so long to respond (school, etc)

I'm actually trying to read in compressed world map data which is in the format:
int width, int height, unsigned char data[width*height]
from a compressed file. So I take huffman compression algo, and load the file, decompress it. I then have an array of data, but i would like to load the width and height right from that binary array, instead of resaving it to a file first, then loading it.

If this isnt possible.. I will make my own binary numeral format (char[0]*255+char[1] or similiar)

Thanks again
~Zix~

Share this post


Link to post
Share on other sites
Solias    564
Ok here is a "sread" function that does what fread does, except on a byte array (could be char, but let's be explicit). Please note I am not actually suggesting this function is the best way to do this, my hope is that by understanding it you can solve your problem.


size_t sread(void *buffer, size_t size, size_t count, BYTE *stream, size_t *position, size_t length) {

if(*position + (size * count) > length) {
count = (length - *position) / size;
}

memcpy(buffer, stream + *position, size * count);
*position = *position + (size * count);
return count;
}



Now it's important to understand that there are a few differences between a file stream and a c array. The first difference is that streams store their own size, c arrays do not. sread gets around this by passing in the length of the array as the "length" param. You could also use a more complex structure such a a vector which tracks it's own length. The if statement modifies count to prevent overflowing the arrray.

A second difference is that files track a file pointer which is updated after every read. Since arrays don't track the last read you made, sread does it with the position param. Note that position is a pointer, so changes made to it will not be limited to the scope of the function.

The real meat of the function is the call to memcpy, which actually copies the data from the array to your buffer.

Now, once again I'm not claiming this is the best way to do this. This is all c code and it's written for clarity, not efficiency. My goal here was to give you exactly what you asked for to help you understand how c arrays work compared to c file streams.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this