Welcome to Dream.In.Code
Getting C++ Help is Easy!

Join 109,550 C++ Programmers for FREE! Ask your question and get quick answers from experts. There are 1,258 online right now! We've got more than 500 tutorials and 2,000 snippets. Join and find out why Dream.In.Code is the #1 programming help community on the internet! Registration is fast and FREE... Join Now!



WCHAR Array into a char*

 
Reply to this topicStart new topic

WCHAR Array into a char*, got a couple problems

UG Cyber
post 7 Aug, 2008 - 11:26 PM
Post #1


New D.I.C Head

*
Joined: 24 Jul, 2008
Posts: 32

Ok, the main project objective is to list all the files then its the user's choice on wich to open.
How ever in the process of turning the WCHAR into a char* it only decrypts every other letter.
for instance. If the filename was Hello.txt it would say Hlott

Here is the code in question but keep in mind that all the includes arn't used in this snippet, there for future use

CODE

#include <iostream>
#include <fstream>
#include <windows.h>
#include <winable.h>
#include <stdio.h>
using namespace std;

WIN32_FIND_DATA FindFile;
HANDLE hFindFile;
char FileCharArray[1024];

char* Convert(const WCHAR * const wcharArray)
{
      int i = 0;
      
      while (true)
      {          
               char buff;
               buff = (char) wcharArray[i];
               if ( buff != '\0' )
               {
                    FileCharArray[i] = buff;
                    i++;
            }
            else
            {
                 return FileCharArray;
            }
      }
}

int main(void)
{
    char* Returned;
    hFindFile = FindFirstFile("*.*", &FindFile);
    if (hFindFile == INVALID_HANDLE_VALUE)
    {
                     cout << "No files found!!"<< endl;
                     Sleep(3000);
                     return 1;
    }
    Returned = Convert((WCHAR*)FindFile.cFileName);
    cout << Returned << endl;
    Sleep(2000);
    
       while (FindNextFile(hFindFile, &FindFile))
       {
    if (hFindFile == INVALID_HANDLE_VALUE)
    {
                     cout << "No files found!!"<< endl;
                     Sleep(3000);
                     return 1;
    }
    Returned = Convert((WCHAR*)FindFile.cFileName);
    cout << Returned << endl;
    Sleep(2000);
    }
    return 0;
}


Any ideas??
User is offlineProfile CardPM

Go to the top of the page


perfectly.insane
post 8 Aug, 2008 - 02:56 AM
Post #2


D.I.C Addict

Group Icon
Joined: 22 Mar, 2008
Posts: 515



Thanked 38 times
My Contributions


Is there any particular reason against using WideCharToMultiByte?

Also, note that cFileName in the WIN32_FIND_DATA structure is defined as TCHAR, not WCHAR. This means if your program is compiled without the _UNICODE and UNICODE preprocessor defintions set, then this will be actually a CHAR array, not a WCHAR array. That would explain the behavior, I believe (as each WCHAR is actually holding two characters, so you only get every other character.)

This post has been edited by perfectly.insane: 8 Aug, 2008 - 03:00 AM
User is offlineProfile CardPM

Go to the top of the page

UG Cyber
post 8 Aug, 2008 - 10:20 AM
Post #3


New D.I.C Head

*
Joined: 24 Jul, 2008
Posts: 32

QUOTE(perfectly.insane @ 8 Aug, 2008 - 02:56 AM) *

Is there any particular reason against using WideCharToMultiByte?

Also, note that cFileName in the WIN32_FIND_DATA structure is defined as TCHAR, not WCHAR. This means if your program is compiled without the _UNICODE and UNICODE preprocessor defintions set, then this will be actually a CHAR array, not a WCHAR array. That would explain the behavior, I believe (as each WCHAR is actually holding two characters, so you only get every other character.)


I am completly new to this subject....How would i define UNICODE and _UNICODE.
and what are the param's to WidCharToMultiByte??
User is offlineProfile CardPM

Go to the top of the page

perfectly.insane
post 8 Aug, 2008 - 01:33 PM
Post #4


D.I.C Addict

Group Icon
Joined: 22 Mar, 2008
Posts: 515



Thanked 38 times
My Contributions


Do you actually need to use Unicode? If not, then you should be able to use FindFile.cFileName directly without converting it (as it's defined as char* or const char* when _UNICODE and UNICODE are not #defined (which it doesn't seem like it for you now)). And if you do want to use Unicode, and #define _UNICODE and UNICODE, then you can use wcout as opposed to cout to print the contents to the console.

Here is a description of WideCharToMultiByte (even though you don't really even need it):

http://msdn.microsoft.com/en-us/library/ms776420(VS.85).aspx

So right now, cout << FindFile.cFileName << endl; should work for you.

This post has been edited by perfectly.insane: 8 Aug, 2008 - 01:35 PM
User is offlineProfile CardPM

Go to the top of the page

UG Cyber
post 8 Aug, 2008 - 11:16 PM
Post #5


New D.I.C Head

*
Joined: 24 Jul, 2008
Posts: 32

Well i tryed just to have the program to open it using fstream and it cant open it??

cpp

ofstream fout;
fout.open(FindFile.cFileName);
if (!fout)
{
cout << "Could not open " << FindFile.cFileName << endl;
}
fout.close();


I replaced the Convert(FindFile.cFileName); with the code above so it didnt mess with the char* at all.
and of course i always get the error message "Could not open BLAH.txt". The compiler has no problems with it(Borland builder 6 and Dev). Is it possible hiding whitespaces are throwing off the fout.open();
User is offlineProfile CardPM

Go to the top of the page

perfectly.insane
post 9 Aug, 2008 - 07:57 AM
Post #6


D.I.C Addict

Group Icon
Joined: 22 Mar, 2008
Posts: 515



Thanked 38 times
My Contributions


Well, if the file given doesn't already exist, it should create it. So if it's not returning the existing file exactly, I'd think that it would still create a file. Also, the operation that you're doing seems a bit strange. Iterate through all files, and then truncate them? That is what you'll do by opening the files for writing without specifying any flags, I believe. What kind of permissions do you have in the directory where you're executing this?

(The fact that it's printing the correct file name to the output stream is a good sign. I've never have seen FindFirstFile/FindNextFile return file names with superfluous characters, by the way).

This post has been edited by perfectly.insane: 9 Aug, 2008 - 08:01 AM
User is offlineProfile CardPM

Go to the top of the page

ChazZeromus
post 9 Aug, 2008 - 09:13 PM
Post #7


New D.I.C Head

*
Joined: 2 Aug, 2008
Posts: 11


My Contributions


Conversion from a wide char to a single char is easy, a wide char is a signed word. So you could just write your own conversion process easy. This means that a the value of 'A' in a single char is the same in wide char. All you have to do is just cast a char to wide char.

So you're trying to write a routine that takes a wide char string and flattens it into a single char eh?
Now if the routine was doing the conversion the other way around then it would be quite dangerous, lol. Btw, to use this routine your making, you'll have mandatorily cast your input string.

Try this(Be sure to use a different pointers for each type so you increment the pointer properly):
CODE

char* ChazWcharToChar(wchar_t* wstr) {
     char* cstr = (char*)wstr, *ostr = cstr;
     while (1)
     {
         if (*wstr == 0)
            break;
         *cstr = *wstr;
           ++cstr;
           ++wstr;
     }
     return ostr;
}

Try that, by the way it isn't completely safe, just rough code.
A word of warning, I just tried to correct what you tried to do, please don't use this routine on initialized data like this:
CODE

wchar_t* str = L"HAHAH";
ChazWcharToChar(str);

This will not work and will cause an access violation because str string points to your program's read only data.

This post has been edited by ChazZeromus: 9 Aug, 2008 - 09:20 PM
User is offlineProfile CardPM

Go to the top of the page

perfectly.insane
post 9 Aug, 2008 - 09:16 PM
Post #8


D.I.C Addict

Group Icon
Joined: 22 Mar, 2008
Posts: 515



Thanked 38 times
My Contributions


That should work provided that all of the characters are below 128, and is not a multi-byte encoding like UTF-8. If one has characters 128-255, then those characters are usually specific to a code page, and different code pages have different mappings to UCS-2 characters.

There is mbstowcs and wcstombs, but these are broken on Windows MSVCRT (they do not support UTF-8).

This post has been edited by perfectly.insane: 9 Aug, 2008 - 09:19 PM
User is offlineProfile CardPM

Go to the top of the page

ChazZeromus
post 9 Aug, 2008 - 09:30 PM
Post #9


New D.I.C Head

*
Joined: 2 Aug, 2008
Posts: 11


My Contributions


QUOTE(perfectly.insane @ 9 Aug, 2008 - 09:16 PM) *

That should work provided that all of the characters are below 128, and is not a multi-byte encoding like UTF-8. If one has characters 128-255, then those characters are usually specific to a code page, and different code pages have different mappings to UCS-2 characters.

There is mbstowcs and wcstombs, but these are broken on Windows MSVCRT (they do not support UTF-8).

I know, i was just assuming all he cared about was <= 128.
User is offlineProfile CardPM

Go to the top of the page

Reply to this topicStart new topic
Time is now: 9/7/08 10:35PM

Live C++ Help!

C++ Tutorials

Reference Sheets

C++ Snippets

Bye Bye Ads

Free DIC T-Shirt

T-Shirt Example

Related Sites

Monthly Drawing

Thumb Drive

Partners

Top Contributors

Top 10 Kudos This Month