wchar concatenating and stuff (c++)

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

Recommended Posts

im trying to get a sound file's filename (in wChars) by a function call to a method. it basically takes 3 parts: a. L"sfx/sound/battle/" b. an eight wchar lookup from a file titled battle.bin c. L".wav" here is how im doing it:

WCHAR* getSoundFilename (int soundID){

WCHAR* filename = (WCHAR*) malloc (30*sizeof(WCHAR));
WCHAR filepart[8];

FILE * pFile;

pFile = fopen ("sfx/sound/battle/battle.bin","r");
fseek (pFile , 8*sizeof(WCHAR)*soundID , SEEK_SET );
fclose(pFile);

wcsncat(filename,L"sfx/sound/battle/", 17);
wcsncat(filename, filepart, 8);
wcsncat(filename, L".wav", 4);

return filename;
}

I can tell you from debugging that the contents of 'filepart look right. There is nothing wrong with the file lookup, or the battle.bin's format. However, when im returning the filename, it looks like i have 30 WCHARs worth of uninitialized in front of the correctly formatted filename. I think it's concatenating the wchars to the end of whatever space was reserved by the malloc call, or something. But im not sure what to do about this

Share on other sites
Any reason you can't just use std::wstring?

Share on other sites
no idea. how do you mean? like if i do:

std::wstring str(L"sfx/sound/battle/");

or something? I'm not seeing how this is any different. Sorry, i just found out about this datatype today and im not familiar with how to work with it too well.

Share on other sites
Yeah does it work with just using std::string?
I'd try that first then try making it work with wstring.

Share on other sites
Quote:
 Original post by sqpatno idea. how do you mean? like if i do:std::wstring str(L"sfx/sound/battle/");or something? I'm not seeing how this is any different. Sorry, i just found out about this datatype today and im not familiar with how to work with it too well.

For example, concatenating two wide strings:
std::wstring str(L"Hello ");str += L"World!";

That simple.

Always prefer C++ string objects (std::string, std::wstring) over C-strings.

Share on other sites
Ugh. While that does make things a LOT easier, this directX function requires a WCHAR* filename argument. I tried the .c_str() method of wstring but that returns a wchar_t*, and i have no idea how to convert wstring or wchar_t* to wchar*. Google's got nothing either.

Sorry, im new to C++, ive mostly used C. Strings were always easiest in QBasic :)

Share on other sites
WCHAR is just a typedef for wchar_t. c_str() should work fine for any Windows API or DX functions. [smile]

I made a blog post a while back about strings and character sets, you might find it a bit useful.

PS: don't worry about being confused, I assure you myself and plenty of others were just as confused when we started working with this stuff.

Share on other sites
i think i figured it out;

c_str() returned a const wchar_t. So i had to do this:

return const_cast<wchar_t*>(filename.c_str());

i'm not even quite sure what a const_cast is so i should probably look it up incase im returning an invalid pointer, lol.

Share on other sites
Casting const-ness away from a pointer returned by c_str() is really nothing more than an invitation to blow up the whole thing.

In your case, however, it looks like you are now trying to return a pointer into an object that goes out of scope when the function ends (the pointer becomes a dangling pointer immediately).

Why not return the wstring itself instead? Is there any reason why you think the caller should have to deal with messy pointers, now that you have comfortably implemented this function with a higher-level object?

Share on other sites
all right, i got it working. the const_cast cant be returned that way. here is how i went about it:

void getSoundFilename (int soundID, wchar_t* returnVal){        WCHAR filepart[9];    FILE * pFile;	pFile = fopen ("sfx/sound/battle/battle.bin","r");	fseek (pFile , 8*sizeof(WCHAR)*soundID , SEEK_SET );	fread(filepart, sizeof(WCHAR), 8, pFile);	fclose(pFile);	filepart[8] = 0x0000;	std::wstring filename(L"sfx/sound/battle/");	filename.append(filepart);	filename += L".wav";	wcscpy(returnVal, const_cast<wchar_t*>(filename.c_str()));}

note a couple differences; i had to append a null terminator (0x0000) to the end of 'filepart' now that i wasnt using the concatenation. I also changed it from returning a value to storing the value in a passed in pointer, because the const wchar_t that was being spit out by c_str() made this more convenient.

EDIT: 1.learn to use code tag correctly
2. can strings be returned? i thought they were just beautified char arrays. I basically stopped using strings because of how hard-assed C was about them. Either way, i need WCHAR* and its much cleaner to do that conversion inside the function rather than outside of the function after it returns a wstring.

Share on other sites
isn't there some sort of flag for the compiler to automatically assume that all strings should be treated like wstrings?

Share on other sites
it probably varies from compiler to compiler.

but i dont know if thats a good idea; youre bound to need string sooner or later. Plus, char is great just as a general data type. you can just designate a wstring with L"stuff goes here", and a string with "stuff goes here" when you need either one.

Share on other sites
Quote:
 Original post by owlisn't there some sort of flag for the compiler to automatically assume that all strings should be treated like wstrings?

If you #define the "UNICODE" macro, then the TCHAR type in the Windows API evaluates to WCHAR instead of CHAR. The "_UNICODE" macro does the same for the _TCHAR type in the C standard library.

Of course this does nothing for any strings explicitly declared using char or wchar_t.

Share on other sites
interesting. It'd be cool if that worked for std:strings

Share on other sites
The bug in your original post was that you never set filename[0] to L'\0' before calling wcnscat(), i.e. you were concatenating to a garbage string. Or you could replace the first call to wcsncat() with wcsncpy(). Either would work.

Share on other sites
Quote:
 Original post by SlyThe bug in your original post was that you never set filename[0] to L'\0' before calling wcnscat(), i.e. you were concatenating to a garbage string. Or you could replace the first call to wcsncat() with wcsncpy(). Either would work.

good point. in retrospect that must've been it, because i had to fix that bug similarly on the newer implementation, except it was with filepart[8] this time.