Archived

This topic is now archived and is closed to further replies.

Reading strings of unknown size-how?

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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!!

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
Kwizatz, you are overflowing your "szBuffer" if the string is bigger than 1024 char''s. Anytime you use static fixed-length buffers like that with unbounded-length data you''re probably opening yourself up to an overflow.

Julio, I don''t know where you''re getting "each line can be a max of 255", but''s it''s not true in general. A standard null terminated C string can be as big as you want it to be regardless of whether it''s in memory or in a file.

-Mike

Share this post


Link to post
Share on other sites
Mike, you are right on the overflow, now that I think about it, so, may not be a good Idea after all, only if you are confident the strings wont be bigger than your buffer. Thanks for pointing it out.

Julio, MAX_PATH which is the constant size for maximum path/filename lenght is 255 I believe in windows9x (not sure about NT/2000) so thats probably where you are mistaken, this means a string that contains a path to a file cannot be more than 255, doesnt mean you cant have strings bigger.

if the string you save in your file is meant to be a path then just replace 1024 in my code above with MAX_PATH and unless someone deliverately changes the file path to contain more chars, overflowing may not be an issue.

Share this post


Link to post
Share on other sites


My implementation won''t overflow, becuase it always reads BufferSize chars, and looks for the first null terminator in there. If it finds one, it backs up the file pointer to the character after it, otherwise, it reads again.

There, a 1 paragraph explanation of my algorithm.

Share this post


Link to post
Share on other sites