Marshaling - conversion std::vector<char> to string^ And conversely - c++

I use 2 method for these conversion
// Vector to String.
VectorToString(std::vector<char> data)
{
const char* newData = &data[0];
String ^result;
result = marshal_as<String^>(newData);
return result;
}
// String to vector
StringToVector(String ^ data)
{
marshal_context ctx;
IntPtr p = Marshal::StringToHGlobalAnsi(data);
const char* pAnsi = static_cast<const char*>(p.ToPointer());
// use pAnsi
std::vector<char> result;
result.assign(pAnsi, pAnsi + strlen(pAnsi));
Marshal::FreeHGlobal(p);
return result;
}
with 2 above function I can doing convert.
can you tell me these conversion is correct? or not?
actually, this way for convert std::vector to String is best way?

you must be add #include msclr/marshal_cppstd.h
vector to String ^
vector<char> data;// this is be initialize
std::string myString = std::string(begin(data), end(data));
String^ result = marshal_as<String^>(myString);
string ^ to vector
marshal_context context;
std::vector<char> myVector;
const char* afterConvert = context.marshal_as<const char*>(data);
myVector.assign(afterConvert , afterConvert + strlen(afterConvert));

Related

Dynamic array of fixed length strings

How do I create a dynamic array of fixed length strings?
I created class AString which has pointers to struct _str which has fixed-length array data.
How to assign values, and what is wrong?
#include "stdafx.h"
#include <iostream>
struct _str {
char data[20];
};
class AString {
public:
AString();
~AString();
void Add(_str string);
private:
_str *str;
int count;
};
AString::AString() {
std::cout << "Constructor" << std::endl;
str = nullptr;
count = 0;
}
AString::~AString() {
std::cout << "Destructor" << std::endl;
if (str != nullptr) delete[] str;
}
void AString::Add(_str string) {
_str *str2 = new _str[count+1];
for (int i=0;i<count;i++) {
str2[i] = str[i];
}
delete[] str;
str = str2;
count++;
str[count-1] = string;
}
int _tmain(int argc, _TCHAR* argv[])
{
AString astring;
_str str1;
str1.data="0123456789012345678"; // cannot convert from 'const char[20]' to 'char[20]'
astring.Add(str1);
std::cin.get();
return 0;
}
str1.data="0123456789012345678";: cannot convert from 'const char[20]' to 'char[20]'
Want to:
not use _str str1;, and use char str1[20];
As for me, I used this:
strcpy(str1.data, "0123456789012345678");
Here is the main:
int main(int argc, char* argv[])
{
AString astring;
_str str1;
//str1.data=const_cast<char>("0123456789012345678"); // cannot convert from 'const char[20]' to 'char[20]'
strcpy(str1.data, "0123456789012345678");
astring.Add(str1);
std::cout << str1.data;
std::cin.get();
return 0;
}
The result is as follows:
Constructor
0123456789012345678
First of all, I would recomend you yo use std::string or std::array. But if you forced to use char[], I would recomend you to use strncpy instead of operator =, so it would looks like this
strncpy(str1.data,"0123456789012345678", 20); // cannot convert from 'const char[20]' to 'char[20]'
To copy char* or block of memory, it is better to use memcpy!
void* memcpy (void* destination, const void* source, size_t length);
It copies the values of length bytes starting the location pointed to by source directly to the memory block pointed to by destination. Note that, the underlying type of the objects pointed to by both the source and destination pointers dose not matter.
You can also use strncpy.
char* strncpy(char* destination, const char* source, size_t length);
It works properly for your code but if there is/are some 0 valued bytes, the strncpy consider it as null-termination and coping continued with '0' i.e. (pad) until length is satisfied.
try
memcpy(str1.data, "0123456789012345678", 20);
You can't assign to arrays - that's just the way it is.
You could use strncpy in main, or get an assignable array with std::array<char, 20>, but if there was a need to do this by hand, I would add constructors (and hide the implementation details) in order to keep things safe:
class _str {
public:
typedef char base[20];
_str() { data[0] = 0; }
_str(const base& in) { strncpy(data, in, 20); }
const base& get() const { return data; }
private:
base data;
};
and then you can
AString astring;
_str str1 = "01234567890123456789"; // Fine
astring.Add(str1);
std::cout << str1.get();
_str str2 = "012345678901234567890"; // Compilation error
_str str3 = "0"; // Compilation error

pass array of strings to a function which takes const char**

I have a function which takes an array of const char** as a parameter
void Foo(const char** bar);
I can pass an array of const char * to it
const char *bar[2];
bar[0] = "test";
bar[1] = "me";
Foo(bar); // works fine
I want to do the same when 'bar' is std::string array instead of const char *
std::string bar[2];
bar[0] = "test";
bar[1] = "me";
Foo(bar); // cannot convert argument 1 from 'std::string [1]' to 'const char **'
I know the way convert std::string to const char *. Is there any way I can do it in the above case
Not sure what you're trying to achieve exactly but here
// Example program
#include <iostream>
#include <string>
void Foo(const char** bar, int num) {
while(num > 0) {
std::cout << bar[--num] << std::endl << std::flush;
}
}
const char** toCharArray(std::string* arr, int num) {
// If we ever alloc with new with have to delete
const char** buffer = new const char*[num];
for(int i = 0; i < num; i++) {
buffer[i] = arr[i].c_str();
}
return buffer;
}
int main()
{
std::string bar[2];
bar[0] = "test";
bar[1] = "me";
// Capture the result
const char** charBar = toCharArray(bar, 2);
Foo(charBar, 2);
// So we can free it later
delete[] charBar;
}
Arrays in memory do not have a length or size member like other languages so we pass in the size via function arguments. Second since we want to pass in an array of strings and get an array of chars out of it, we'll need to construct another array dynamically. Only way to do this is to use new. This stores the chars on the heap instead of the stack so when the function toCharArray finishes, the data will live on. So we store the result in charBar so that we can delete[] the array later.
you cannot do it directly
auto arr = std::vector<const char*>();
auto s1 = std::string("test");
auto s2 = std::string("me");
arr.push_back(s1.c_str());
arr.push_back(s2.c_str());
Foo(arr.data());

c++ float to const wchar_t* converting function

I'm converting a float to a const wchar_t *
DisplayText(ConversionUtils::FloatToWstring(fps).c_str()); // Prints garbage
DisplayText(std::to_wstring(fps).c_str()); // Doesn't print anything to the device.
with this function :
std::wstring ConversionUtils::FloatToWstring(float value) {
return std::to_wstring(value);
}
I want to get something like that :
DisplayText(ConversionUtils::FloatToConstWcharPtr(fps));
Just return by value:
std::wstring ConversionUtils::FloatToWchar(float value) {
std::string str = std::to_string(value);
return std::wstring(str.begin(), str.end());
}
Or better, use std::to_wstring() instead.

Converting from C++ string to unsigned char* and back

What would be the code to convert an std::string to unsigned char* and back?
str = "1234567891234567"
unsigned char* unsignedStr = ConvertStrToUnsignedCharPointer(str);
str1 = ConvertUnsignedCharToStr(unsignedStr);
str and str1 must be same with no loss of precision.
auto str1 = std::string{"1234567891234567"}; // start with string
auto chrs = str.c_str(); // get constant char* from string
auto str2 = std::string{ chrs }; // make string from char*
Unsigned char*:
auto uchrs = reinterpret_cast<unsigned char*>(const_cast<char*>(chrs));
Using vectors instead of raw pointers:
using namespace std;
auto str1 = string{"1234567891234567"};
vector<char> chars{ begin(str1), end(str1) };
vector<unsigned char> uchars;
transform(begin(str1), end(str1), back_inserter(uchars),
[](char c) { return reinterpret_cast<unsigned char>(c); });

C++ String and char * c stype strings

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);
}