Can not convert LPTSTR to std::string in release mode - c++

Just like the title says, I can not convert LPTSTR to std::string in release mode. In other words, when I'm doing this:
LPTSTR lpt;
std::string str = lpt;
This only works when I'm in debug mode. The compiler says that no matching constructor could be found. Did I forget to include something?

I tried this function
#include <string>
using namespace std;
string LPTSTRToString(LPTSTR Input)
{
string Output;
for (int i=0;i<((wstring)Input).length();i++)
Output+=Input[i];
return Output;
}

Related

Quick C++ Query RE returning Strings from a function

I am updating my "C++" knowledge to the latest version using Unicode Strings etc..
Can someone please just confirm than creating a String within a function and Returning it is Valid? and it will retain the actual String data.
Below is a cut-down "nonsense" function, but is this "legal" and "safe" regarding creating & returning the String.? My testing suggests it is, but I would not notice if some memory was freed but not cleared.
#include <vcl.h>
#include <wchar.h>
#include <stdio.h>
UnicodeString MyUTFToUnicode (WideChar *In);
int _tmain(int argc, _TCHAR* argv[])
{
UnicodeString Test;
WideChar In[] = L"My Wide String";
Test = MyUTFToUnicode(In);
wprintf(L"%s\n",Test.c_str());
return 0;
}
UnicodeString MyUTFToUnicode (WideChar *In)
{
WideChar wc[500];
UnicodeString Out;
swprintf(wc,500,L"Hello This is The Input String : %s", In);
Out = wc;
return Out;
}
Regards

Creating a file with variable name in c++

so I want to create a file but the name of it will be dependent on the user input e.g. if the user types "shrek" the file must be named "shrek.txt". Thats what I came up with but it doesn't work.
int main(){
ofstream file;
string name = "abc";
file.open(name + ".txt");
file.close();
}
I guess you are using an old C++ standard. If that's the case, fstream::open won't accept a std::string, only a C string (char*). You can use c_str in your string to obtain a const char* that will be accepted:
int main(){
ofstream file;
string name = "abc";
string file_name = name + ".txt";
file.open(file_name.c_str()); // <- here
file.close();
}
However, it's recommendable to switch to a more modern standard, as your code actually works for C++11 and newer.
Do you have the libraries required? In this case #include fstream. Does the same issue happens to another complier? Check that out. I attempted this myself and your code surely works. Attempt to use my code which I confirm works and see if you have any issues.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main() {
string name;
cin>> name;
ofstream file(name +".txt");
file.close();
}

STL/Boost Replacement for WideCharToMultiByte-function

In the following code (snippet) WideCharToMultiByte is a Windows specific function.
Is there a suitable replacement for the function using STL or Boost?
//in function parameters: (..., WCHAR* szNameOfDll, ...)
char szSourceTemp[MAX_PATH + 1] = {0};
WideCharToMultiByte(CP_ACP,0,szNameOfDLL,-1, szSourceTemp,MAX_PATH,NULL,NULL);
Any help appreciated!
std::wctomb/std::wcstombs
std::mbtowc/std::mbstowcs
or
#include <boost/locale.hpp>
#include <iostream>
std::string utf8_string = to_utf<char>(latin1_string,"Latin1");
std::wstring wide_string = to_utf<wchar_t>(latin1_string,"Latin1");
std::string latin1_string= from_utf(wide_string,"Latin1");
std::string utf8_string2 = utf_to_utf<char>(wide_string);

Converting 'const char*' to 'LPCTSTR' for CreateDirectory

#include "stdafx.h"
#include <string>
#include <windows.h>
using namespace std;
int main()
{
string FilePath = "C:\\Documents and Settings\\whatever";
CreateDirectory(FilePath, NULL);
return 0;
}
Error: error C2664: 'CreateDirectory' : cannot convert parameter 1 from 'const char *' to 'LPCTSTR'
How do I make this conversion?
The next step is to set today's date as a string or char and concatenate it with the filepath. Will this change how I do step 1?
I am terrible at data types and conversions, is there a good explanation for 5 year olds out there?
std::string is a class that holds char-based data. To pass a std::string data to API functions, you have to use its c_str() method to get a char* pointer to the string's actual data.
CreateDirectory() takes a TCHAR* as input. If UNICODE is defined, TCHAR maps to wchar_t, otherwise it maps to char instead. If you need to stick with std::string but do not want to make your code UNICODE-aware, then use CreateDirectoryA() instead, eg:
#include "stdafx.h"
#include <string>
#include <windows.h>
int main()
{
std::string FilePath = "C:\\Documents and Settings\\whatever";
CreateDirectoryA(FilePath.c_str(), NULL);
return 0;
}
To make this code TCHAR-aware, you can do this instead:
#include "stdafx.h"
#include <string>
#include <windows.h>
int main()
{
std::basic_string<TCHAR> FilePath = TEXT("C:\\Documents and Settings\\whatever");
CreateDirectory(FilePath.c_str(), NULL);
return 0;
}
However, Ansi-based OS versions are long dead, everything is Unicode nowadays. TCHAR should not be used in new code anymore:
#include "stdafx.h"
#include <string>
#include <windows.h>
int main()
{
std::wstring FilePath = L"C:\\Documents and Settings\\whatever";
CreateDirectoryW(FilePath.c_str(), NULL);
return 0;
}
If you're not building a Unicode executable, calling c_str() on the std::string will result in a const char* (aka non-Unicode LPCTSTR) that you can pass into CreateDirectory().
The code would look like this:
CreateDirectory(FilePath.c_str(), NULL):
Please note that this will result in a compile error if you're trying to build a Unicode executable.
If you have to append to FilePath I would recommend that you either continue to use std::string or use Microsoft's CString to do the string manipulation as that's less painful that doing it the C way and juggling raw char*. Personally I would use std::string unless you are already in an MFC application that uses CString.

Converting System::String to Const Char * [duplicate]

This question already has answers here:
how to convert System::String to const char*?
(2 answers)
Closed 7 years ago.
I am using Visual C++ 2008's GUI creator to make a user interface. When a button is clicked, the following function is called. The content is supposed to create a file and name the file after the contents of the textbox "Textbox' with '.txt' at the end. However, that leads me to a conversion error. Here is the code:
private: System::Void Button_Click(System::Object^ sender, System::EventArgs^ e) {
ofstream myfile (Textbox->Text + ".txt");
myfile.close();
}
Here is the error:
error C2664: 'std::basic_ofstream<_Elem,_Traits>::basic_ofstream(const char *,std::ios_base::openmode,int)' : cannot convert parameter 1 from 'System::String ^' to 'const char *'
How can I do a conversion to allow this to go through?
I would use marshalling:
//using namespace System::Runtime::InteropServices;
const char* str = (const char*)(void*)
Marshal::StringToHGlobalAnsi(Textbox->Text);
// use str here for the ofstream filename
Marshal::FreeHGlobal(str);
But note that you then use just Ansi strings. If you need unicode support you can use the widechar STL class wofstream and PtrToStringChars (#include <vcclr.h>) to convert from System::String. In that case you do not need to free the pinned pointer.
It's simple!
As you're using managed C++, use the include and operate like:
#include <msclr/marshal.h>
...
void someFunction(System::String^ oParameter)
{
msclr::interop::marshal_context oMarshalContext;
const char* pParameter = oMarshalContext.marshal_as<const char*>(oParameter);
// the memory pointed to by pParameter will no longer be valid when oMarshalContext goes out of scope
}
#include <string>
#include <iostream>
#include <atlbase.h>
#include <atlconv.h>
#include <vcclr.h>
using namespace System;
int main(array<System::String ^> ^args)
{
String^ managedStr = gcnew String(L"Hello, Managed string!");
//If you want to convert to wide string
pin_ptr<const wchar_t> wch = PtrToStringChars(managedStr);
std::wstring nativeWstr(wch);
//if you want to convert to std::string without manual resource cleaning
std::string nativeStr(CW2A(nativeWstr.c_str()));
std::cout<<nativeStr<<std::endl;
Console::WriteLine(L"Hello World");
return 0;
}
Thanks jdehaan. I little modified the code to use it with my 'normal' System::String's.
void MarshalNetToStdString(System::String^ s, std::string& os)
{
using System::IntPtr;
using System::Runtime::InteropServices::Marshal;
const char* chars = (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer( );
os = chars;
Marshal::FreeHGlobal(IntPtr((void*)chars));
}
This is the way if you want to convert System:String -> std:string.
You can convert it to a CString and then add the extension to it.
There is a built-in CString constructor which will allow this conversion to happen
Example:
CString(Textbox->Text)
In your specific case:
private: System::Void Button_Click(System::Object^ sender, System::EventArgs^ e)
{
ofstream myfile (CString(Textbox->Text) + ".txt");
myfile.close();
}
There is an really excellent article in MSDN about String conversions here:
http://msdn.microsoft.com/en-us/library/ms235631%28vs.80%29.aspx
There are many samples to convert String from and to different types.