How can I copy a CHAR Variable to WCHAR Variable in C++ - c++

I want to convert a CHAR file to UNICODE file.
I read a file character by character in CHAR file type and then save this character in a CHAR Variable and then I want to copy this CHAR Variable to a WCHAR Variable and then I Write the the WCHAR Variable in to a UNICODE file.
here is the code :
#include<Windows.h>
#include<tchar.h>
int _tmain(int argc, LPCTSTR argv[])
{
HANDLE hInfile, hOutfile;
CHAR f1;
WCHAR f2;
DWORD Rd, Wrt;
INT i;
CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL,NULL);
CreateFile(argv[2], GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);
while ((ReadFile(hInfile, &f1, sizeof(CHAR), &Rd, NULL) && Rd>0))
{
**_tccpy(f2, f1);**
WriteFile(hOutfile, &f2, Rd, &Wrt, NULL);
}
CloseHandle(hInfile);
CloseHandle(hOutfile);
}
in bold code is the problem, how can I copy CHAR Variable to a WCHAR Variable.
the _tccpy function and strcpy function cant do this, because the prototype of both of them is char or wachar.

Microsoft Specific
Use wmain instead of main if you want to write portable code that adheres to the Unicode programming model.
wmain( int argc, wchar_t *argv[ ], wchar_t *envp[ ] )
wmain at ms http://msdn.microsoft.com/en-us/library/bky3b5dh(VS.80).aspx

I have always found these string basics and conversions very useful when dealing with Unicode in C++.

Related

"cannot convert 'wchar_t*' to 'LPCSTR' {aka 'const char*'}gcc" when trying to use WriteConsoleOutputCharacter()

So, I'm trying to use "Windows.h" to output unicode characters on console with wchar_t*, and I found on internet that this is the code I'm supposed to use:
wchar_t *screen = new wchar_t[nScreenWidth*nScreenHeight];
HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
SetConsoleActiveScreenBuffer(hConsole);
DWORD dwBytesWritten = 0;
while(1) {
screen[nScreenWidth * nScreenHeight - 1] = '\0';
WriteConsoleOutputCharacter(hConsole, screen, nScreenWidth * nScreenHeight, { 0,0 }, &dwBytesWritten);
}
However, when I try to compile, I get this error: cannot convert 'wchar_t*' to 'LPCSTR' {aka 'const char*'}gcc
I'm compiling with mingw64 and I'm using this command:
"-std=c++20",
"-g",
"${workspaceFolder}/*.cpp",
"-L",
"${workspaceFolder}\\src\\lib",
"-I",
"${workspaceFolder}\\src\\include",
"-l",
"mingw32" ,"-l",
"SDL2main" ,"-l",
"SDL2",
"-o",
"main",
(I'm technically also using SDL2, but I don't need it at the moment)
Thank you!!
WriteConsoleOutputCharacter is a macro of WriteConsoleOutputCharacterW or WriteConsoleOutputCharacterA depends on the charset compiler option.
WriteConsoleOutputCharacterW accepts LPCWSTR (a.k.a const WCHAR* a.k.a const wchar_t *, or const unsigned short * if wchar_t is not supported by the compiler) as parameter.
WriteConsoleOutputCharacterA accepts LPCSTR (a.k.a const char *) as parameter.
So, checkout your compiling settings, and make sure which version you are actually calling, and define your screen as the right type.
If not sure or you want support both, you could use TCHAR string/buffer instead. TCHAR is a macro of WCHAR or char depends on the same compiler option. And LPCSTR/LPSTR is macros of the pointer types.

WriteConsole access violation in function call but not from main()

I am trying to use WriteConsole(..) in a function call but I get access violation. When I un-comment the code in main, it prints my text to the screen with no problem in the main function. When I try to print the string in the function call I get access violation even though it does print the text to the console.
void print(char *_charArray);
int _tmain(int argc, _TCHAR* argv[])
{
HWND hConsole;
// HANDLE hFile;
char myText[] = "This is my text";
char *pMyText = myText;
LPDWORD charsWriten;
// hFile = CreateFile("CONOUT$", GENERIC_WRITE, FILE_SHARE_READ, NULL,
// OPEN_EXISTING, 0, NULL);
print(pMyText);
// WriteConsole(hFile, myText, sizeof(myText), charsWriten, NULL);
getch();
return 0;
}
void print(char *text)
{
LPDWORD charsWriten;
HANDLE hFile;
hFile = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE | FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, NULL);
unsigned int strn = strlen(text) + 1;
if(!WriteConsole(hFile, text, (strlen(text) + 1), charsWriten,NULL))
{
printf("Write Failed\n");
}
}
This declaration is wrong:
LPDWORD charsWriten;
The CreateFile function expects the fourth parameter to be a pointer to a variable it can write into. You don't actually allocate memory, though; you just declare a pointer—an uninitialized one at that. That won't work. You need to do:
DWORD charsWritten;
...
WriteConsole(hFile, text, (strlen(text) + 1), &charsWritten, NULL)
That will fix the access violation problem, but it doesn't explain why you are writing one character past the end of your string. You don't need to add 1 to strlen; the terminating NUL doesn't need to be written.
LPDWORD charsWriten;
LPDWORD is DWORD*. So what you have there is an uninitialized pointer. You then pass this pointer to WriteConsole, which writes to the invalid location pointed to. Instead, declare charsWritten as type DWORD, and pass its address to WriteConsole with &charsWritten.
DWORD charsWritten;
WriteConsole(hFile, text, (strlen(text) + 1), &charsWritten, NULL);
If, as you say, it works as you have it in main. That is simply bad luck. It's undefined behavior, which doesn't always have predictable results.

Conversion from TCHAR to std::string, other way than using WideCharToMultiByte?

I have to convert a TCHAR variable (which is a path retrieved with OpenBrowseDir) into a std::string.
I'm currently having this code which works. I'm using WideCharToMultiByte.
TCHAR path[MAX_PATH];
OpenBrowseDir(path);
/*conversion from TCHAR to std::string*/
char ch[MAX_PATH];
char DefChar = ' ';
WideCharToMultiByte(CP_ACP, 0, path, -1, ch, MAX_PATH, &DefChar, NULL);
string spath(ch);
On my project TCHAR is wchar_t.
In OpenBrowseDir I'm opening a browse dialog so the user can select a directory. I'm using a variable BROWSEINFO bi, and bi.pszDisplayName is of type TCHAR.
Are there other better solutions?

C++: convert LPTSTR to char array [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Convert lptstr to char*
I need to convert an LPTSTR p to CHAR ch[]. I am new to C++.
#include "stdafx.h"
#define _WIN32_IE 0x500
#include <shlobj.h>
#include <atlstr.h>
#include <iostream>
#include <Strsafe.h>
using namespace std;
int main(){
int a;
string res;
CString path;
char ch[MAX_PATH];
LPTSTR p = path.GetBuffer(MAX_PATH);
HRESULT hr = SHGetFolderPath(NULL,CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, p);
/* some operation with P and CH */
if(SUCCEEDED(hr))
{ /* succeeded */
cout << ch;
} /* succeeded */
else
{ /* failed */
cout << "error";
} /* failed */
cin >> a;
return 0;
}
Thanks in advance.
LPTSTR is a (non-const) TCHAR string. Depends if it is Unicode or not it appears. LPTSTR is char* if not Unicode, or w_char* if so.
If you are using non-Unicode strings LPTSTR is just a char*, otherwise do:
size_t size = wcstombs(NULL, p, 0);
char* CharStr = new char[size + 1];
wcstombs( CharStr, p, size + 1 );
Also, this link can help:
Convert lptstr to char*
LPTSTR means TCHAR* (expanding those Win32 acronyms typedefs can make it easier to understand them). TCHAR expands to char in ANSI/MBCS builds, and to wchar_t in Unicode builds (which should be the default in these days for better internationalization support).
This table summarizes the TCHAR expansions in ANSI/MBCS and Unicode builds:
| ANSI/MBCS | Unicode
--------+----------------+-----------------
TCHAR | char | wchar_t
LPTSTR | char* | wchar_t*
LPCTSTR | const char* | const wchar_t*
So, in ANSI/MBCS builds, LPTSTR expands to char*; in Unicode builds it expands to wchar_t*.
char ch[MAX_PATH] is an array of char's in both ANSI and Unicode builds.
If you want to convert from a TCHAR string (LPTSTR) to an ANSI/MBCS string (char-based), you can use ATL string conversion helpers, e.g.:
LPTSTR psz; // TCHAR* pointing to something valid
CT2A ch(psz); // convert from TCHAR string to char string
(Note also that in your original code you should call CString::ReleaseBuffer() which is the symmetric of CString::GetBuffer().)
Sample code follows:
// Include ATL headers to use string conversion helpers
#include <atlbase.h>
#include <atlconv.h>
...
LPTSTR psz = path.GetBuffer(MAX_PATH);
HRESULT hr = SHGetFolderPath(NULL,CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, psz);
path.ReleaseBuffer();
if (FAILED(hr))
{
// handle error
...
}
// Convert from TCHAR string (CString path) to char string.
CT2A ch(path);
// Use ch...
cout << static_cast<const char*>(ch) << endl;
Note also that the conversion from Unicode to ANSI can be lossy.
First, you defined char* ch[MAX_PATH] instead of char ch[MAX_PATH].
Regarding your question, LPTSTR (Long Pointer to TCHAR String) is equivalent to LPWSTR (which is w_char*) if it's unicode, or just LPSTR (char*) if it is not. You can use this link for reference about conversion in each case.
EDIT: To cut to the chase, here's some code:
if (sizeof(TCHAR) == sizeof(char)) // String is non-unicode
strcpy(ch, (char*)(p));
else // String is unicode
wcstombs(ch, p, MAX_PATH);
EDIT 2: In windows I would recommend using TCHAR instead of char. It will save you some headache.
EDIT 3: As a side note, if you want to prevent Visual Studio from flooding you with warnings about unsafe functions, you can add something like the following to the very beginning of your code:
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

call avio_open function with non-english filename is invalid

i have been writing unicode based program with libav and i wanna make some file through libav with filename "中.mp4".
this filename is not english, and when i call, function return positive integer(not fail).
but there is "ѱ۰.mp4" instead of "中.mp4". (invalid file name.)
what's the matter?
char * szFilenameA = 0;
#ifdef _UNICODE
CSHArray<char> aFilenameBuffer;
aFilenameBuffer.Alloc(lstrlen(szFileName) * 2);
ZeroMemory(aFilenameBuffer, aFilenameBuffer.GetSize());
WideCharToMultiByte(CP_ACP, 0, szFileName, lstrlen(szFileName), aFilenameBuffer, aFilenameBuffer.GetSize(), NULL, NULL);
szFilenameA = aFilenameBuffer;
#else
szFilenameA = (TCHAR *)szFileName;
#endif
ZeroMemory(m_pOutputFormatCtx->filename,1024);
_snprintf(m_pOutputFormatCtx->filename, strlen(szFilenameA), "%s", szFilenameA);
avio_open(&m_pOutputFormatCtx->pb, szFilenameA, AVIO_FLAG_WRITE)
finally!
it's because of charset.
convert ansi filename to UTF8 and then it works fine.
int ANSIToUTF8(char *pszCode, char *UTF8code)
{
WCHAR Unicode[100]={0,};
char utf8[100]={0,};
// read char Lenth
int nUnicodeSize = MultiByteToWideChar(CP_ACP, 0, pszCode, strlen(pszCode), Unicode, sizeof(Unicode));
// read UTF-8 Lenth
int nUTF8codeSize = WideCharToMultiByte(CP_UTF8, 0, Unicode, nUnicodeSize, UTF8code, sizeof(Unicode), NULL, NULL);
// convert to UTF-8
MultiByteToWideChar(CP_UTF8, 0, utf8, nUTF8codeSize, Unicode, sizeof(Unicode));
return nUTF8codeSize;
}