I am trying to cout a basic_string<TCHAR>. But cout is throwing error. Can I know how to do that
As dauphic said, std::wcout is for wide strings and std::cout for narrow ones. If you want to be able to compile for either type of string (TCHAR is meant to make this sort of thing easier) something like this sometimes makes life easier:
#if defined(UNICODE) || defined(_UNICODE)
#define tcout std::wcout
#else
#define tcout std::cout
#endif
With this in place use tcout instead.
TCHAR is a winapi define for the character type used by your application. If you have the character set as multi-byte characters, it will be char. If you have it set to Unicode, it will be wchar_t.
If it's wchar_t, you need to use std::wcout. Otherwise, just plain std::cout should be fine.
Generally it helps to also explain what errors you're getting, but most likely you're trying to insert an std::basic_string<wchar_t> into std::cout, and there probably isn't an operator<< overload for that.
As #Bo Persson mentioned, another way of defining a tcout type would be using references with the correct stream types. Though there are a few more things to consider when doing that, as you'll easily end up with linker issues due to multiple or missing definitions.
What works for me is declaring these types as external references in a header and defining them once in a source file. This also works in a precompiled header (stdafx).
Header
namespace std
{
#ifdef UNICODE
extern wostream& tcout;
#else
extern ostream& tcout;
#endif // UNICODE
}
Implementation
namespace std
{
#ifdef UNICODE
wostream& tcout = wcout;
#else
ostream& tcout = cout;
#endif // UNICODE
}
Related
According to MSDN:
https://msdn.microsoft.com/en-us/library/windows/desktop/ff381407%28v=vs.85%29.aspx
You can write TCHAR for char or wchar_t depend on compiler MACRO UNICODE
Is there a similar symbol for std::string and std::wstring?
Thanks!
(My VC++ version is 2013)
You could define it yourself:
typedef basic_string<TCHAR, char_traits<TCHAR>, allocator<TCHAR> > tstring;
I did not find one. I wrote one myself in my code like this -
#ifdef UNICODE
#define tstring std::wstring
#else
#define tstring std::string
#endif
You can also tweak a bit by adding the namespace in your stdafx.h
namespace std {
typedef basic_string<TCHAR, char_traits<TCHAR>, allocator<TCHAR> > tstring;
}
I've read that one can use SHGetSpecialFolderPath(); to get the AppData path. However, it returns a TCHAR array. I need to have an std::string.
How can it be converted to an std::string?
Update
I've read that it is possible to use getenv("APPDATA"), but that it is not available in Windows XP. I want to support Windows XP - Windows 10.
The T type means that SHGetSpecialFolderPath is a pair of functions:
SHGetSpecialFolderPathA for Windows ANSI encoded char based text, and
SHGetSpecialFolderPathW for UTF-16 encoded wchar_t based text, Windows' “Unicode”.
The ANSI variant is just a wrapper for the Unicode variant, and it can not logically produce a correct path in all cases.
But this is what you need to use for char based data.
An alternative is to use the wide variant of the function, and use whatever machinery that you're comfortable with to convert the wide text result to a byte-oriented char based encoding of your choice, e.g. UTF-8.
Note that UTF-8 strings can't be used directly to open files etc. via the Windows API, so this approach involves even more conversion just to use the string.
However, I recommend switching over to wide text, in Windows.
For this, define the macro symbol UNICODE before including <windows.h>.
That's also the default in a Visual Studio project.
https://msdn.microsoft.com/en-gb/library/windows/desktop/dd374131%28v=vs.85%29.aspx
#ifdef UNICODE
typedef wchar_t TCHAR;
#else
typedef unsigned char TCHAR;
#endif
Basically you can can convert this array to std::wstring. Converting to std::string is straightforward with std::wstring_convert.
http://en.cppreference.com/w/cpp/locale/wstring_convert
You should use SHGetSpecialFolderPathA() to have the function deal with ANSI characters explicitly.
Then, just convert the array of char to std::string as usual.
/* to have MinGW declare SHGetSpecialFolderPathA() */
#if !defined(_WIN32_IE) || _WIN32_IE < 0x0400
#undef _WIN32_IE
#define _WIN32_IE 0x0400
#endif
#include <shlobj.h>
#include <string>
std::string getPath(int csidl) {
char out[MAX_PATH];
if (SHGetSpecialFolderPathA(NULL, out, csidl, 0)) {
return out;
} else {
return "";
}
}
Typedef String as either std::string or std::wstring depending on your compilation configuration. The following code might be useful:
#ifndef UNICODE
typedef std::string String;
#else
typedef std::wstring String;
#endif
I am trying to do the following:
class sig
{
CComboBox objList;
void SetDefault();
}
void sig :: SetDefault()
{
objList.InsertString(0, METHOD_ONE);
}
I have defined METHOD_ONE in a different class as
#define METHOD_ONE "OFF"
And I get the above error.
Can somebody please help me?
Cheers,
Chintan
The most important part is to understand the error; know what is a const char [4], is the easy part but, what about the LPCTSTR?
According to the Microsoft documentation:
An LPCWSTR if UNICODE is defined, an LPCSTR otherwise. For more
information, see Windows Data Types for Strings.
And the LPCWSTR is:
A pointer to a constant null-terminated string of 16-bit Unicode characters. For more information, see Character Sets Used By Fonts.
First, you must check out what type of encoding are using your program; it seems that you're using UNICODE, so in the end you're trying to convert a const pointer to chars (the "OFF" constant) to a const pointer to wchar_t, and (logically) the conversion isn't allowed.
Then, you can choose the correct string type; if UNICODE is defined, your #define must be wide string:
// Note the L
#define METHOD_ONE L"OFF"
You can also define it this way:
#ifdef UNICODE
#define METHOD_ONE L"OFF"
#else
#define METHOD_ONE "OFF"
#endif
Or use the _T macro suggested by Roman R. The only that this macro does is to append L prefix to the text:
#ifdef UNICODE
#define _T(x) L ##x
#else
#define _T(x) x
#endif
In the end, you must be aware of what kind of string are using; but Microsoft is hidding it by using an obscure chain of #defines and typedefs.
I'm using a library and sends me std::wstring from one of its functions, and another library that requires _TCHAR [] to be sent to it. How can I convert it?
Assuming you're using Unicode build, std::wstring.c_str() is what you need. Note that c_str() guarantees that the string it returns is null-terminated.
e.g.
void func(const wchar_t str[])
{
}
std::wstring src;
func(src.c_str());
If you're using non-Unicode build, you'll need to convert the Unicode string to non Unicode string via WideCharToMultiByte.
As #Zach Saw said, if you build only for Unicode you can get away with std::wstring.c_str(), but conteptually it would be better to define a tstring (a typedef for std::basic_string<TCHAR>) so you can safely use this kind of string flawlessly with all the Windows and library functions which expect TCHARs1.
For additional fun you should define also all the other string-related C++ facilities for TCHARs, and create conversion functions std::string/std::wstring <=> tstring.
Fortunately, this work has already been done; see here and here.
Actually no compiled library function can really expect a TCHAR *, since TCHARs are resolved as chars or wchar_ts at compile time, but you got the idea.
Use the ATL and MFC String Conversion Macros. This works regardless of whether you are compiling in _UNICODE or ANSI mode.
You can use these macros even if you aren’t using MFC. Just include the two ATL headers shown in this example:
#include <string>
#include <Windows.h>
#include <AtlBase.h>
#include <AtlConv.h>
int main()
{
std::wstring myString = L"Hello, World!";
// Here is an ATL string conversion macro:
CW2T pszT(myString.c_str());
// pszT is now an object which can be used anywhere a `const TCHAR*`
// is required. For example:
::MessageBox(NULL, pszT, _T("Test MessageBox"), MB_OK);
return 0;
}
For some reason I need to temporarily disable some macros in a header file and the #undef MACRONAME will make the code compile but it will undef the existing macro.
Is there a way of just disabling it?
I should mention that you do not really know the values of the macros and that I'm looking for a cross compiler solution (should work at least in GCC and MSVC).
In MSVC you could use push_macro pragma, GCC supports it for compatibility with Microsoft Windows compilers.
#pragma push_macro("MACRONAME")
#undef MACRONAME
// some actions
#pragma pop_macro("MACRONAME")
Using just the facilities defined by Standard C (C89, C99 or C11), the only 'disable' mechanism is #undef.
The problem is there is no 're-enable' mechanism.
As others have pointed out, if the header file containing the macro definitions is structured so that it does not contain any typedef or enum declarations (these cannot be repeated; function and variable declarations can be repeated), then you could #undef the macro, do what you need without the macro in effect, and then re-include the header, possibly after undefining its protection against reinclusion.
If the macros are not defined in a header, of course, you are stuck until you refactor the code so that they are in a header.
One other trick is available - if the macros are function-like macros and not object-like macros.
#define nonsense(a, b) b /\= a
int (nonsense)(int a, int b)
{
return (a > b) ? a : b;
}
The function nonsense() is defined fine, despite the macro immediately before it. This is because a macro invocation - for a function-like macro - must be immediately followed by an open parenthesis (give or take white space, possibly including comments). In the function definition line, the token after 'nonsense' is a close parenthesis, so it is not an invocation of the nonsense macro.
Had the macro been an argument-less object-like macro, the trick would not work:
#define nonsense min
int (nonsense)(int a, int b)
{
// Think about it - what is the function really called?
return (a > b) ? a : b;
}
This code defines a bogus function that's called min and is nonsensical. And there's no protection from the macro.
This is one of the reasons why the standard is careful to define which namespaces are reserved for 'The Implementation'. The Implementation is allowed to define macros for any purpose it desires or needs, of any type (function-like or object-like) it desires or needs, provided those names are reserved to the implementation. If you as a consumer of the services of The Implementation try to use or define a name reserved to the implementation, you must be aware that your code will probably break sooner or later, and that it will be your fault, not the fault of The Implementation.
Macros make my knees go weak, but wouldn't the most universal solution be to restructure your code so that you wouldn't need to reenable the macro again in the same source file? Wouldn't it be possible to extract some code into a separate function and a separate source file where you can undef the offending macro.
The macros come from some header file, so you should have access to their values. You can then do something like
#include <foo.h> // declares macro FOO
// Do things with FOO
#undef FOO
// do things without FOO
#include <foo.h> // reenable FOO
Your header should then be designed along these lines
#ifndef FOO
#define FOO do_something(x,y)
#endif
EDIT:
You may think that it's that easy:
#ifdef macro
#define DISABLED_macro macro
#undef macro
#endif
// do what you want with macro
#ifdef DISABLED_macro
#define macro DISABLED_macro
#endif
But it's not (like the following example demonstrates)!
#include <iostream>
#include <limits>
#include <windows.h>
#ifdef max
#define DISABLED_max max
#undef max
#endif
int main()
{
std::cout << std::numeric_limits<unsigned long>::max() << std::endl;
#ifdef DISABLED_max
#define max DISABLED_max
#endif
std::cout << max(15,3) << std::endl; // error C3861: "max": identifier not found
return 0;
}
Using #undef on the macro and re-including the original header is also not likely to work, because of the header guards.
So what's left is using the push_macro/pop_macro #pragma directives.
#pragma push_macro("MACRO")
#undef MACRO
// do what you want
#pragma pop_macro("MACRO")
There are specific rules for function-like macroses invokation in C/C++ language.
The function-like macroses have to be invoked in the following way:
Macros-name
Left parethesis
One token for each argument separated by commas
Each token in this list can be separared from another by whitespaces (i.e. actual whitespaces and commas)
With one trick you "disable preprocessor mechanism" with breaking rules for function-like macro invokation, but be still within a rules of function calling mechanism...
#include <iostream>
using namespace std;
inline const char* WHAT(){return "Hello from function";}
#define WHAT() "Hello from macro"
int main()
{
cout << (*WHAT)() << "\n"; // use function
cout << (WHAT)() << "\n"; // use function
cout << WHAT () << "\n"; // use macro
return 0;
}