Reading strings of unknown size-how?

Started by
11 comments, last by TheGecko 22 years, 9 months ago
Hey again people, I have this little problem and I have a basicc idea of how to go aobut it but I wanted to see what you guys think first.It involves strings and I usually hate working with strings.Anyway, suppose I have a binary file that contains a string which is the filename of a texture map for example.My Milkshape exporter plugin exported the name of the texture file to this binary file.Now,the exporter exported 15 chars to the binary file (the filname of the texture map is 15 chars long).What I want to know is,how does my Actor class that''s reading this file know how long that string is (the texture map filename string)? The one way I though of was to save the length of the string along with the string itself in the file.Is there a better way? Thanx for any help
Advertisement
Silly answer but, why not terminated it with a null? You know that a null cannot be a valid member of a string so when you hit it you know the string is finished.
Chris Brodie
The problem he''s probably running in to is that if you don''t know how long the string is in advance, you don''t know how much memory to allocate for it.

There''s two solutions, you can read the string twice - once to size it and once to read it into a buffer. Or you can just malloc a buffer that seems big enough for most cases and if it turns out it''s to small use realloc to get a bigger buffer.

Or you can just put the length before the string.

-Mike
-Mike
Mike has the classic answer, put the string length out front. I usually define some kind of master "crap buffer" that I can refer to in the procedure or class when I need a scratchpad for those kinds of things. In those cases I just read up to the first null, and I''m done. I suppose that could be the first CR/LF, too.
--------------
-WarMage
SPOON!!
...store it as a BSTR
--Tr][aD--
Heh, I tried this just for the heck of it. I wanted to see if I could read a string from disk w/o knowing anything about its length, only that it has a null-terminator. It could be a single character (and a null), just a null, or a novel.

I exploit the string class''s += operator. I start with an empty string, then I read in a const number of bytes and add it to the string. I check to see if a null is in there, if there is, set the file pointer to be one after that null, otherwise, fillup the buffer again.

Here''s the source for it:

  static void ReadString( FILE *f,string& s ) // reads s at file pointer{    static const BufferSize = 1024;     // size of buffer/read    static char  Buffer[BufferSize];    // buffer    // parse next BufferSize bytes for the first completed string and return it    string Completed;    bool ReadEnd = false;    while( !ReadEnd )    {        // read buffer        int BytesRead = fread( Buffer,sizeof( char ),BufferSize - 1,f );        // affix manual terminator (to make sure strlen doesn''t break)        if( BytesRead < BufferSize )            Buffer[BytesRead] = 0;        else            Buffer[BufferSize - 1] = 0;        // cache length of read string        int Length = strlen( Buffer );        // tack read string to completed        Completed += Buffer;        // handle completed strings        if( (Length < BytesRead) || (Length == 0) )        {            // seek back to first null terminator            fseek( f,Length - BytesRead + 1,SEEK_CUR );            ReadEnd = true;        }    }    s = Completed;}//---------------------------------------------------------------------------  


I wouldn''t say it''s entirely efficient, but it works and you don''t need an encoded length, so it''ll read any string.

Hope it helps in some way.

Thank you for your bandwidth.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~Succinct Demos Online~
I am a software engineer who writes poetic code!
-- Succinct(Don't listen to me)
Thanx for all your replies guys.I''ve tried all your ideas but in the end,I found out that if I just save the length of the string in the file as well,then that would save me alot of headache and make my work alot easier.All is working fine now though.Thanx again!

why not?:
      #include <stdio.h>FILE *stream;void main( void ){   char szBuffer[1024];   char *pszData;   stream = fopen( "yourfile.bin", "r" );   fscanf( stream, "%s", szBuffer );   pszData = new char[strlen(szBuffer);   strcpy(pszData,szBuffer);   fclose( stream );   printf("%s\r\n",pszData);   delete [] pszData;}    

I know its got strcpy in it but you are creating a buffer that is the size of the string, buffer overflow is not a problem I think, and in any case you can use a std::string and set it to be what is readed from szBuffer like so:
        #include <stdio.h>FILE *stream;std::string sData;void main( void ){   char szBuffer[1024];   stream = fopen( "yourfile.bin", "r" );   fscanf( stream, "%s", szBuffer );   sData = szBuffer;   fclose( stream );   printf("%s\r\n",sData.c_str());   delete [] pszData;}      

HTH

Edited by - kwizatz on June 27, 2001 11:23:50 AM

Edited by - kwizatz on June 27, 2001 3:31:34 PM
you could use the eof flag. something like:
  while(!file.eof){parse();}  

each line can be a max of 255, so just set that as your max for each line.

HHSDrum@yahoo.com
Polarisoft Home Page
My HomepageSome shoot to kill, others shoot to mame. I say clear the chamber and let the lord decide. - Reno 911
Julio: It may not be a file of strings, though, just a file that has strings in certain places.
-- Succinct(Don't listen to me)

This topic is closed to new replies.

Advertisement