how can i use fread to read from char *

Started by
19 comments, last by ChaosEngine 6 years, 11 months ago

i get an error i dont see why



template <class T> stream_read(T *& dst, int count, int *& index, char * src)
{
char * psrc = &src[(*index)];
memcpy(dst, src, (size_t)count);
(*index) = (*index) + 4;
psrc = 0;
}


inline AnsiString loadstringstream(int *& index, char * data)
{
int len;
stream_read(&len, 4, index, data); //error here
[BCC32 Error] global_vars.h(37): E2285 Could not find a match for 'stream_read<T>(int *,int,int *,char *)'
}

i am not sure if i can use *&

template <class T> stream_read(T *& dst, int count, int *& index, char * src)

*& basically means that i want to change values at this address (two ints that have to be changed) in this case

Advertisement
i get an error i dont see why

1) Your stream_read function is missing a return value declaration => void stream_read

2) When you pass by pointer-reference (*&), you need to pass an actual pointer variable => &len creates a temporary pointer value, which cannot be bound to the pointer-reference.


void test(int *& pointer)
{
}

// bad:
int x;
test(&x); 

good:
int* p;
test(p); // => can modify the pointers address

Why are you passing pointer-references here anyways? Your code doesn't need to modify the address of eigther "dst" nor "index", so just pass by regular pointer, or better yet references:


template <class T>
void stream_read(T& dst, size_t count, int& index, const char* src)
{
    memcpy(&dst, src, count);
    index += 4;
}

(there have also been a few WTFs, which really makes you wonder for such a small amount of code, like passing in int and casting to (size_t) for "count", or not using the += operator specially since you use pointer-aritmetic on both sides of the assignment etc...)

crap! since i need to use return type i cant use only one function.

theres no question at all i just post code



inline int read_int_from_stream(int count, int & index, char * src)
{
char * psrc = &src[index];
int dst;
memcpy(&dst, psrc, (size_t)count);
index = index + count;
psrc = 0;

return dst;
}

inline char * read_pchar_from_stream(int count, int & index, char * src)
{
char * psrc = &src[index];
char * dst = new char[ count + 1 ];
memcpy(dst, psrc, (size_t)count);
index = index + count;
psrc = 0;
dst[count] = 0;
return dst;
}


inline AnsiString loadstringstream(int & index, char * data)
{
int len = read_int_from_stream(4, index, data);

char * p = read_pchar_from_stream(len, index, data);

//p[len] = 0;

AnsiString str = AnsiString(p, len);
delete [] p;
p = 0;
return str;
}

AnsiString is std::string

I think you should look again at Nypyrens suggestion.

The equivalent code to your latest posted, using just pointer casts would be this:


inline AnsiString loadstringstream(int & index, char * data)
{
int len = *(int*)(data + index);
AnsiString str{(data + index + sizeof(int)),len};
index += len + sizeof(int);
return str;
}
 

And that's it! No unnecessary copies and allocations.

no shortcuts allowed code needs to be readable for everyone/everything

What is a "shortcut"? What makes the code not "readable for everyone"?

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

You should also consider the possibility that the reader and writer have different endianness.


mistake *

Is this C or C++?

If it's C++ you should be using vector and ifstream, instead of new[] and fread. At the very least, wrap your FILE pointer in a smart pointer that will close it on destruction.

if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight

This topic is closed to new replies.

Advertisement