SFML community forums
Help => Graphics => Topic started by: JollyRoger on December 12, 2009, 04:40:51 am
-
Hi, I'm trying to load a font from memory, because I plan to use a custom font file type in the future already used in my engine.
Right now, though, I'm just trying to load a file into a std::string, and then use font.LoadFromFile( ) to get the font.
This is the code I'm using:
std::string& OpenFile( std::string filename )
{
int length;
char* buffer;
std::string* encrypted;
std::ifstream file;
file.open( filename.c_str( ), std::ios::binary | std::ios::ate );
file.seekg( 0, std::ios::end );
length = file.tellg( );
file.seekg( 0, std::ios::beg );
buffer = new char[ length ];
file.read( buffer, length );
file.close( );
*encrypted = buffer;
delete( buffer );
return( *encrypted );
}
And this is the code I use to load the font:
sf::Font font;
std::string file = OpenFile( "Arial.ttf" );
font.LoadFromMemory( file.c_str( ), file.length( ) );
The file is valid, and the error I get from SFML is an invalid stream operation.
Any help is appreciated.
-
std::string* encrypted;
...
*encrypted = buffer;
encrypted is not allocated. Why do you use a pointer here?
-
Thanks. I was working with two similar functions, I allocated the string in one, but not the other.
I figured out that one reason it wasn't working was because I was deleting the buffer, so it was trying to access memory that wasn't there. I ended up just having the function return the buffer instead of a std::string.
Thanks for the help.
-
I figured out that one reason it wasn't working was because I was deleting the buffer, so it was trying to access memory that wasn't there.
No, your pointer to std::string wasn't initialized, as Laurent said.
I ended up just having the function return the buffer instead of a std::string.
I think, that's a bad idea because the invoker is now responsible for the memory. Why don't you use std::string? C-String char arrays have got a lot of problems.
Some improvement suggestions:
// return a std::string copy (not reference) and pass a const-reference
std::string OpenFile( const std::string& filename )
{
// use constructor
std::ifstream file( filename.c_str( ), std::ios::binary | std::ios::ate );
file.seekg( 0, std::ios::end );
length = file.tellg( );
file.seekg( 0, std::ios::beg );
// don't declare variables far before they are used
int length; // initialize length
char* buffer = new char[ length ];
file.read( buffer, length );
file.close( );
// don't declare variables far before they are used, again
std::string encrypted = buffer;
// use delete[] for arrays!
delete buffer;
// return copy (parentheses aren't required)
return encrypted;
}
-
Thank you for taking the time to post those improvements.
-
Thank you for taking the time to post those improvements.
No problem, I like to help (especially if people don't just ignore my advice). :)
P.S.: I hope, you saw that some of the code is still wrong, for example the use of delete instead of delete[]. However, the errors should be described in comments.