I have const void *pString which is a Pointer to the string to analyze. Assume it hold a value ABCD, I want to get the string ABCD from it, can someone help ?
When I try to use char *ptr = (char *) pString; then use
ptr[0] it gives A
ptr[1] it gives empty
ptr[2] it gives B
ptr[3] it gives empty and so on.
Use WCHAR string for ScriptStringAnalyse(),
then
...
wstring ws(...);
string str(ws.begin(), ws.end());
...
str[0]
WCHAR helped out here and I was able to get the output using the below snippet:
const WCHAR *ptr = (const WCHAR *)pString;
char *pmbbuf = (char*) malloc(len + 1);
if (pmbbuf != NULL) {
wcstombs(pmbbuf, (LPCWSTR) ptr, len);
string str = string(pmbbuf);
}
Related
I have an input string, and I want to find how many spaces are there in the string.
Here's my code
// input string
std::string str = "abc d e f";
// convert string to cstring
char* cstr = new char[str.length()+1];
std::strcpy(cstr, str.c_str());
// iterate through the cstring and count how many spaces are there
int num_of_spaces = 0;
char* ptr = cstr;
while (ptr) {
if (*ptr == ' ') {
++num_of_spaces;
}
++ptr;
}
However, I got an error message on the if (*ptr == ' ') line that says: Thread 1: EXC_BAD_ACCESS (code = 1, address=0x100200000)
Isn't *ptr a char type value because ptr is a char* pointer and I dereferenced it to *ptr. If so, why the comparison is not valid?
You don't want while (ptr), you want while (*ptr), that is, while the thing ptr points to isn't a zero character which marks the end of a C-style string.
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());
}
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);
char ParseCmd(char *buf,int len)
{
char *p;
p = strtok(buf," ");
return *p;
}
Why does this function only return first symbol in a whole buffer? If I set buffer to a "fsa rew qwe" it returns only "f" instead of the expected "fsa".
"mˣ*" - that is now im getting. why ?
char dum = *InstList->Lines->GetText();
LoadLibrary("SyntaxP.dll");
char *dum1 = ParseCmd(&dum,32);
InstList->Lines->Add(dum1);
Because your return type is char which represents a character and you dereference the pointer returned by strtok().
Because you are returning a char value, which means only the first character of the string pointed by pointer p.You should return a char * from your function.
Your function should have the prototype:
char* ParseCmd(char *buf,int len);
^^^^^
Online Demo:
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
char* ParseCmd(char *buf,int len)
{
char *p;
p = strtok(buf," ");
char *ptr = (char *)malloc(strlen(p)+1);
strncpy(ptr,p,strlen(p));
return ptr;
}
int main()
{
char array[]="fsa rew qwe";
char* ret = ParseCmd(array,11);
printf("[%s]",ret);
/*If You Forget this,You cause a Memory Leak*/
free(ret);
return 0;
}
Output:
[fsa]
Disclaimer: I have not really used any C++ in the code because since You are using strtok and char * instead of string I believe the Q is more C than C++.
Like any C-style string, p is actually a character array. If you dereference it, you get a character. Have your ParseCmd return p instead of return *p.
I have a c library which use char arrays as strings and i want to use c++ std::string on my code,
could someone help me how can i convert between char * c style strings and STL library strings ?
for example i have :
char *p="abcdef";
string p1;
and
string x="abc";
char *x1;
how can i convert p to p1 and x to x1
Use string's assignment operator to populate it from a char *:
p1 = p;
Use string's c_str() method to return a const char *:
x1 = x.c_str();
From char* to std::string :
char p[7] = "abcdef";
std::string s = p;
From std::string to char* :
std::string s("abcdef");
const char* p = s.c_str();
You can construct a std::string from a C string thus:
string p1 = p;
You can get a const char * from a std::string thus:
const char *x1 = x.c_str();
If you want a char *, you'll need to create a copy of the string:
char *x1 = new char[x.size()+1];
strcpy(x1, x.c_str());
...
delete [] x1;
string has a constructor and an assignment operator that take a char const* as an argument, so:
string p1(p);
or
string p1;
p1 = p;
Should work. The other way around, you can get a char const* (not a char*) from a string using its c_str() method. That is
char const* x1 = x.c_str();
#include <string.h>
#include <stdio.h>
// Removes character pointed to by "pch"
// from whatever string contains it.
void delchr(char* pch)
{
if (pch)
{
for (; *pch; pch++)
*pch = *(pch+1);
}
}
void main()
{
// Original string
char* msg = "Hello world!";
// Get pointer to the blank character in the message
char* pch = strchr(msg, ' ');
// Delete the blank from the message
delchr(pch);
// Print whatever's left: "Helloworld!"
printf("%s\n", msg);
}