Hi, (This should probably go to comp.lang.c++, but I could not find server
for posting. Sorry.)

I try to read and unpack records from a binary file. The records contain
also a part of
variable, but known length -- say filename -- the length of which is stored
in the fixed
part of the record. (I.e. the record itself has variable length.) The
variable part
is not ASCIIZ -- no terminating zero character.

I am using ifstream object to extract the fixed part of the record into
char buf[known_size]. Then I extract the parts and using the
reinterpret_cast
I store them in member variables of the object that represents the record --
like...

char buf[46];
fin.read(buf, sizeof(buf));
...
m_fname_len = *reinterpret_cast<unsigned short *>(&buf[28]);

No problem here. But once I know the filename length, I want to read that
filename into std::string member variable. I could do something like that
(not heavily tested):
char * p = static_cast<char *>(malloc(m_fname_len));
if (p) {
fin.read(p, m_fname_len);
m_filename.assign(p, m_fname_len);
free(p);
}

Can something similar -- I mean reading a fixed size string from a stream
into std::string -- be done more elegantly, without need to allocate an
extra
buffer?

Thanks for your time and experience,
Petr
--
Petr Prikryl (prikrylp at skil dot cz)

Re: How to read a std::string of known length from binary stream? by Vincent

Vincent
Mon Aug 18 09:17:19 CDT 2003

Petr Prikryl wrote:
> Hi, (This should probably go to comp.lang.c++, but I could not find server
> for posting. Sorry.)

There is no set server
use the one your ISP supplies (if they do) or use google

A solution to avoid the malloc\free would be to use vector<char>

vector<char> ac(m_fname_len)
> if (p) {
> fin.read(&ac[0], m_fname_len);
> m_filename.assign(&ac[0], m_fname_len);
> }

There may be a more direct solution but I can't think of one offhand

Vin


Re: How to read a std::string of known length from binary stream? by Vincent

Vincent
Thu Aug 21 07:55:56 CDT 2003

Petr Prikryl wrote:
> Is the following code correct? Can I assume that
> the string data are continuous the same way
> the data of vector<> are?

No.
That is why I used a vector<char>
The standard doesn't specify that a string be stored in contiguous
memory, it does specify that a vector must be stored that way.

The string version will probably work on most implementations but it's
not guaranteed

> ifstream fin(...); // opened for binary read
> int len = 123456; // lenght of the string in fin
> string s;
>
> // The following is the trick (if corret at all).
> s.assign(len, '\0');
> fin.read(&s[0], len);

A small item on your example is that you can do
string s(len, '\0');
you don't need a separate assign

The advantage of using vector is that it is safe on all implementations.
The advantage of using string is that you have the characters in a
string with all its functions available immediately and no need to
perform a separate copy

Vin


Re: How to read a std::string of known length from binary stream? by Petr

Petr
Fri Aug 22 01:50:23 CDT 2003

Thanks, Vin, for the explanation.

"Vincent Finn" wrote...> Petr Prikryl wrote:
> [...] The string version will probably work on most
> implementations but it's not guaranteed
>
> > ifstream fin(...); // opened for binary read
> > int len = 123456; // lenght of the string in fin
> > string s;
> >
> > // The following is the trick (if corret at all).
> > s.assign(len, '\0');
> > fin.read(&s[0], len);
>
> A small item on your example is that you can do
> string s(len, '\0');
> you don't need a separate assign

Yes. The original string was a member of a class, so
I could not to do that.

Thanks again,
Petr
--
Petr Prikryl (prikrylp at skil dot cz)