Discussion:
filename string manipulation
(too old to reply)
Starglider 4
2010-02-07 00:51:23 UTC
Permalink
I have the following code:

void GLTexture::Load(char *name)
{

// make the texture name all lower case
texturename = _strlwr(_strdup(name));

// strip "'s
if (strstr(texturename, "\""))
texturename = strtok(texturename, "\"");

//> At ths location I want to add "3ds models/" to the filename..
//And I want to have "'s around the complete filename..

// check the file extension to see what type of texture
if(strstr(texturename, ".bmp"))
LoadBMP(texturename);

}

If the char* name would be tex1.bmp, I would want a reslut like "3ds
models/tex1.bmp",
including the "".
I tried several things, like strcat_s() etc. But I coudn't figure it out/
Please help me out.

Thanks,

MK
Giovanni Dicanio
2010-02-07 09:26:03 UTC
Permalink
Post by Starglider 4
void GLTexture::Load(char *name)
{
If the 'name' variable is not modified, I would suggest using const
correctness:

void GLTexture::Load(const char * name );

Moreover, I would suggest using Unicode strings instead of ANSI ones, so:

void GLTexture::Load(const wchar_t * name );
Post by Starglider 4
// make the texture name all lower case
texturename = _strlwr(_strdup(name));
When you call strdup, I think that the function allocates memory, and is
responsibility of the caller (i.e. GLTexture::Load method) to free() it.
I don't see a call to free(), so it seems to me that you are leaking memory
here.
Post by Starglider 4
If the char* name would be tex1.bmp, I would want a reslut like "3ds
models/tex1.bmp",
including the "".
I tried several things, like strcat_s() etc. But I coudn't figure it out/
Please help me out.
Considering that you are using C++ and not pure C, you may want to use a
convenient robust string class.
I like CString (from ATL/MFC), but if you need to write portable C++ code
you should better use std::string (or std::wstring, for Unicode UTF-16
strings).

You may do like this:

const TCHAR * name; // e.g. "tex1.bmp"

CString result;
result.Format( TEXT("\"3ds models/%s\""), name );

The \" escapes the double quotes (") character.
%s is a placeholder for a C (NUL-terminated) string.

HTH,
Giovanni
David Webber
2010-02-07 19:53:48 UTC
Permalink
Post by Starglider 4
void GLTexture::Load(char *name)
{
// make the texture name all lower case
texturename = _strlwr(_strdup(name));
// strip "'s
if (strstr(texturename, "\""))
texturename = strtok(texturename, "\"");
//> At ths location I want to add "3ds models/" to the filename..
//And I want to have "'s around the complete filename..
// check the file extension to see what type of texture
if(strstr(texturename, ".bmp"))
LoadBMP(texturename);
}
If the char* name would be tex1.bmp, I would want a reslut like "3ds
models/tex1.bmp",
including the "".
I tried several things, like strcat_s() etc. But I coudn't figure it out/
Please help me out.
As an alternative to what Giovanni has suggested - if you really want to use
the CRT functions:

Once you've removed the quotes there are api's _makepath and _splitpath
for assembling and deconstructing full paths.

Don't forget to free anything you strdup

Let me underline what Giovanni has said about Unicode - it's best to use
wide character versions of all these strings and APIs - or at least TCHAR
versions so you can move to unicode easily in the future.

Dave
--
David Webber
Mozart Music Software
http://www.mozart.co.uk
For discussion and support see
http://www.mozart.co.uk/mozartists/mailinglist.htm
Tim Roberts
2010-02-07 20:11:53 UTC
Permalink
Post by Starglider 4
void GLTexture::Load(char *name)
{
// make the texture name all lower case
texturename = _strlwr(_strdup(name));
Why do this?
Post by Starglider 4
// strip "'s
if (strstr(texturename, "\""))
texturename = strtok(texturename, "\"");
//> At ths location I want to add "3ds models/" to the filename..
//And I want to have "'s around the complete filename..
No, you don't. File names do not include quotes. If you are building a
command line to run, then you might need to quote the string that you send
to CreateProcess, but when you use the file APIs, NEVER include the quotes.

Why does the incoming name include quotes to begin with?
Post by Starglider 4
// check the file extension to see what type of texture
if(strstr(texturename, ".bmp"))
LoadBMP(texturename);
}
If the char* name would be tex1.bmp, I would want a reslut like "3ds
models/tex1.bmp",
This isn't that hard of a problem. Create a place to hold the string,
initialize it to "3ds models\", then append the file name.

CString texture = "3ds models\\";
texture += name;
LoadBMP(texture);

If you insist on using the painful C API:
char texture[MAX_PATH];
strcpy_s( texture, MAX_PATH, "3ds models\\" );
strcat_s( texture, MAX_PATH, name );
--
Tim Roberts, ***@probo.com
Providenza & Boekelheide, Inc.
legalize+ (Richard)
2010-02-08 08:46:32 UTC
Permalink
[Please do not mail me a copy of your followup]

Two suggestions:

1) Use std::string instead of char *. It saves you from having to do
lots of low-level error-prone code.

2) The Boost.FileSystem library has lots of operations for
manipulating paths and directories in a portable manner.
<http://www.boost.org/doc/libs/1_42_0/libs/filesystem/doc/index.htm>
--
"The Direct3D Graphics Pipeline" -- DirectX 9 draft available for download
<http://legalizeadulthood.wordpress.com/the-direct3d-graphics-pipeline/>

Legalize Adulthood! <http://legalizeadulthood.wordpress.com>
Continue reading on narkive:
Loading...