Currently I'm busy to get some text from the textbox and then convert in into a const char*. I have the following code:
System::String^ host = textBoxHostadres->Text;
const char* host2 = (const char*)(void*)Marshal::StringToHGlobalAnsi(host);
//system(host2); //What to do with this?
Marshal::FreeHGlobal(host2);
It gives a redline (Visual Studio 2012) under Marshal::FreeHGlobal. Can somebody give me a right direction to get the text from the textbox and get it to a const char*? The first line works well and through debugging I see the text get captured.
Update:
System::String^ host = textBoxHostadres->Text;
pin_ptr<const wchar_t> wch = PtrToStringChars(host);
// Convert to a char*
size_t origsize = wcslen(wch) + 1;
const size_t newsize = 100;
size_t convertedChars = 0;
char nstring[newsize];
wcstombs_s(&convertedChars, nstring, origsize, wch, _TRUNCATE);
strcat_s(nstring, " (char *)");
const char* host2 = (const char*)(void*)Marshal::StringToHGlobalAnsi(host);
system(host2);
traceroute hostAddress(host2);
Here you will find all possible conversion between char *, wchar_t*, _bstr_t, CComBSTR, CString, basic_string, and System.String.
The strings types that are covered include char *, wchar_t*, _bstr_t, CComBSTR, CString, basic_string, and System.String. In all cases, a copy of the string is made when converted to the new type. Any changes made to the new string will not affect the original string, and vice versa.
Regarding the EDITs you've added:
It would be nice if you could at least try to understand the code you are copy-pasting. This line strcat_s(nstring, " (char *)"); adds some characters to your string and mainly (char *) and this is obvious now that your nstring doesn't contain an adress of a file allready, but adress + some trash. Also you don't need this line std::cout << nstring << std::endl; at all.
This is how your implementation should look like.
System::String^ host = textBoxHostadres->Text;
pin_ptr<const wchar_t> wch = PtrToStringChars(host);
// Convert to a char*
size_t origsize = wcslen(wch) + 1;
const size_t newsize = 100;
size_t convertedChars = 0;
char nstring[newsize]; // nstring is an array of chars
wcstombs_s(&convertedChars, nstring, origsize, wch, _TRUNCATE);
// strcat_s(nstring, " (char *)"); this line adds trash to your nstring!!!
traceroute hostAddress(nstring);
You were not type-casting host2 in your call to Marshal::FreeHGlobal():
System::String^ host = textBoxHostadres->Text;
const char* host2 = (const char*)(void*)Marshal::StringToHGlobalAnsi(host);
system(host2);
traceroute hostAddress(host2);
Marshal::FreeHGlobal((IntPtr) host2);
Related
So I have this issue
//This holds 5 messages submitted prev by the user, temporarily stored
string arrayOfMessages[5];
lets say
arrayOfMessages[0]="This is my message"//The message in the first position.
I need to copy arrayOfMessages[0] to an array of char like this one;
char message [20];
I tried using strcpy(message,arrayOfMessages[0]) but I get this error :
error: cannot convert 'std::__cxx11::string' {aka 'std::__cxx11::basic_string<char>'} to 'const char*'|
Anyone know how I can accomplish this or if I'm doing something wrong, I cant set the string to be a const char bc the message was imputed prev by the user so it changes every time you run the program thus cannot be a constant variable.
There are many ways of doing it
By using the c_str() function of the string class
string message = "This is my message";
const char *arr;
arr = message.c_str();
By copying all the characters from the string to the char array
string message = "This is my message";
char arr[200];
for(int i = 0; i < 200 && message[i] != '\0'; i++){
arr[i] = message[i];
}
Be careful with the array sizes if you use the second approach.
You can also make it a function in order to make it easier to use
void copyFromStringToArr(char* arr, string str, int arrSize){
for(int i = 0; i<arrSize && str[i] != '\0'; i++){
arr[i] = str[i];
}
}
So in your case you can just call the function like this:
copyFromStringToArr(message,arrayOfMessages[0],20);
Also I am sure there are many more ways to do it but these are the ones I would use.
To copy the contents of std::string into a char[], use c_str():
std::string str = "hello";
char copy[20];
strcpy(copy, str.c_str());
But the datatype of copy must be only char* and not const char*. If you want to assign it to a const char*, then you can use direct assignment:
std::string str = "hello";
const char *copy = str.c_str();
According I build fill a char* from this code :
char* pathAppData = nullptr;
size_t sz = 0;
_dupenv_s(&pathAppData, &sz, "APPDATA");
I can easily construct a string with this code and append this string in the future :
std::string sPathAppData(pathAppData);
sPathAppData.append("\\MyApplication");
But I can't create a wstring from this code. Why is so complicated to work with wstring ? I am going crazy with all theses types.
std::wstring wPathAppData(pathAppData); // Impossible
You could use wchar_t directly and use corresponding wchar_t supported API to retrieve data directly to wchar_t and then construct wstring. _dupenv_s function has a wide counterpart - _wdupenv_s.
Your code then would look like this:
wchar_t* pathAppData = nullptr;
size_t sz = 0;
_wdupenv_s(&pathAppData, &sz, L"APPDATA");
std::wstring wPathAppData(pathAppData);
wPathAppData.append(L"\\MyApplication")
Also this could be an interesting read: std::wstring VS std::string
You have to use iterator to make copy. This is how you can do it.
char* pathAppData = nullptr;
size_t sz = 0;
_dupenv_s(&pathAppData, &sz, "APPDATA");
std::string sPathAppData(pathAppData);
sPathAppData.append("\\MyApplication");
std::wstring wPathAppData(begin(sPathAppData), end(sPathAppData));
wcout << wPathAppData << endl;
I have input strings that contain only digits (just the plain Latin ones, 0-9, so for example "0123"), stored as std::wstring, and I need each as a char*. What's the best way for me to do this? This is my initial approach:
void type::convertWStringToCharPtr(_In_ std::wstring input, _Out_ char * outputString)
{
outputString = new char[outputSize];
size_t charsConverted = 0;
const wchar_t * inputW = input.c_str();
wcstombs_s(&charsConverted, outputString, sizeof(outputString), inputW, input.length());
}
EDIT: The code below works. Thanks all!
void type::convertWStringToCharPtr(_In_ std::wstring input, _Out_ char * outputString)
{
size_t outputSize = input.length() + 1; // +1 for null terminator
outputString = new char[outputSize];
size_t charsConverted = 0;
const wchar_t * inputW = input.c_str();
wcstombs_s(&charsConverted, outputString, outputSize, inputW, input.length());
}
You are not allocating enough memory for your buffer:
char * outputString = new char[input.length()];
Should be
char * outputString = new char[input.length() + 1];
because of terminating NUL-character.
Oh, and also, as per pm100's comment: sizeof(outputString) is giving you the size of the pointer. You should use input.length() + 1, as that is the size of the buffer.
There are a couple of errors in your code. First, you're not allocating enough space in your destination buffer for the NULL character. You must allocate at least input.length() + 1 chars for the function to succeed.
Second, you're not passing in the correct size of the output buffer to the function. sizeof(outputString) returns the size of outputString itself, a char *, and not the number of bytes pointed to by that pointer.
So your function should look like this:
void CoverageTileManager::convertWStringToCharPtr(_In_ std::wstring input, _Out_ char * outputString)
{
size_t outputSize = input.length() + 1;
outputString = new char[outputSize];
size_t charsConverted = 0;
wcstombs_s(&charsConverted, outputString, outputSize, input.c_str(), input.length());
// TODO verify charsConverted = outputSize
}
In C++ I would never use pure pointers: use vector if a char array needed in heap! Do you want to copy the source string? If not, const reference should be used for input. wcstombs_s is used only in Windows, so why doesn't use simply WideCharToMultiByte? Was the conversion success? Return value.
bool CoverageTileManager::convertWStringToCharPtr(const std::wstring& input, std::vector<char>& outputString )
{
if ( input.empty() ) {
return false;
}
int size = WideCharToMultiByte(CP_ACP,0,input.c_str(),input.size(),NULL,0,NULL,NULL);
if ( size <= 0 ) {
return false;
}
outputString.resize(size+1);
if ( WideCharToMultiByte(CP_ACP,0,input.c_str(),input.size(),&outputString[0],size,NULL,NULL) <= 0 ) {
outputString.clear();
return false;
}
outputString[size] = '\0';
return true;
}
Use vector to external C++ lib:
extern void call( const char*, size_t);
std::vector<char> buffer;
std::wstring input;
...
if ( convertWStringToCharPtr(input,buffer) ) {
call(&buffer[0],buffer.size());
}
What is the right way to convert long to char* const in C++?
EDIT:
long l = pthread_self();
ThirdPartyFunction("Thread_Id_"+l); //Need to do this
ThirdPartyFunction(char* const identifierString)
{}
EDIT:
The "proper" way to convert an integer to a string, in C++, is to use a stringstream. For instance:
#include <sstream>
std::ostringstream oss;
ossĀ << "Thread_Id_" << l;
ThirdPartyFunction(oss.str().c_str());
Now, that probably won't be the "fastest" way (streams have some overhead), but it's simple, readable, and more importantly, safe.
OLD ANSWER BELOW
Depends on what you mean by "convert".
To convert the long's contents to a pointer:
char * const p = reinterpret_cast<char * const>(your_long);
To "see" the long as an array of chars:
char * const p = reinterpret_cast<char * const>(&your_long);
To convert the long to a string:
std::ostringstream oss;
oss << your_long;
std::string str = oss.str();
// optionaly:
char * const p = str.c_str();
Another possibile "pure" solution is to use snprintf
long number = 322323l;
char buffer [128];
int ret = snprintf(buffer, sizeof(buffer), "%ld", number);
char * num_string = buffer; //String terminator is added by snprintf
long l=0x7fff0000; // or whatever
char const *p = reinterpret_cast<char const *>(l);
I have two string constants const char * like this:
const char * p1 = "abcd";
const char * p2 = "efgh";
I want to convert these into a single string so that it becomes a file name:
const char * filename = "abcd_efgh.txt";
I tried to concatenate the char * but failed. Kindly guide me as to how to do this.
Thanks
char* are pointers, i.e they hold the address of the memory segment where the data is stored. You need to allocate a new, large enough buffer and then use the strcat() function to concatenate the strings.
This is really the C way to do this, not the C++ way. In C++ you should use a string class, such as std::string which handles all the buffer allocation stuff for you.
I would go with sprintf()
char buffer[strlen(p1) + strlen(p2) + 6];
sprintf(buffer, "%s_%s.txt", abcd, efgh);
(You're adding 6 for the _, .txt, and the \0 to terminate the string; 1 + 4 + 1)
You could use the strcat function:
/* strcat example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[80];
strcpy (str,"these ");
strcat (str,"strings ");
strcat (str,"are ");
strcat (str,"concatenated.");
puts (str);
return 0;
}
You have declared the filename string const, which is too restrictive for what you want to do at runtime, but can be done by the pre-processor at compile time, using the adjacent string rule:
#define PART1 "abcd"
#define PART2 "efgh"
const char* p1 = PART1 ;
const char* p2 = PART2 ;
const char* filename = PART1 "_" PART2 ".txt"
However if you don't need filename to be a const use one of the already proposed solutions.
const std::string p1 = "abcd";
const std::string p2 = "efgh";
std::string filename = p1 + "_" + p2 + ".txt";
Try this:
char name1[] = "my_demo";
char name2[] = "_file.txt";
char* filename = (char*) malloc(sizeof(char) * (strlen(name1) + strlen(name2) + 1));
strcpy(filename, name1);
strcat(filename, name2);
printf("Filename is: %s \n", filename);
free(filename);
Outputs:
Filename is: my_demo_file.txt