output char* to std::string C++ - c++

So given:
struct MemoryStruct {
char *memory;
size_t size;
};
char* memory holds a curl return, XML doc.
I am doing:
if(chunk.memory) {
std::cout << "char size is " << sizeof(chunk.memory) << std::endl;
std::string s = "";
for (int c = 0; c<sizeof(chunk.memory); c++) {
s.push_back(chunk.memory[c]);
}
std::cout << "s: " << s.c_str() << std::endl;
}
I am only getting back <?xm
So sizeof() I think is return the total bytes in the char*
How do I get what the actual value is a char*. So basically the whole curl return. Which is 5 lines of XML?

sizeof(chunk.memory) will give always you size of a pointer which in your case seems to be 4. That's why you see only 4 characters in your std::string.
If your curl return or whatever else is terminated by \0, then you can directly do the following
std::string s(chunk.memory);
If your char * is not terminated by \0, then you need to know the length of the string - you cannot use sizeof(chunk.memory) for this. If your chunk.size contains the correct size, then you can use
std::string s(chunk.memory, chunk.size);

std::string constructor can accept char* and data length (see the docs); Example:
std::string s(chunk.memory, chunk.size);
So container will pre-allocate need space for your string and initialize with it.

In MemoryStruct memory is the pointer to the first returned character and size is the number of characters returned. You want to initialize a string with this data so you will need to do:
s.assign(chunk.memory, chunk.size);

Related

How can i fill a char array with some string , en int

I have a question about a char array:
I have a form '"1"+lapcounter+":"+seconds' that must come in a char array.
How can i fill this array in this form?
Thanks
If you mean you have some numeric variables which you want to format into a string, use a string-stream for that:
std::stringstream ss;
ss << "1" << lapcounter << ":" << seconds";
Now you can extract a string from that:
std::string s = ss.str();
and if you really want a character array for some reason (which I'm sure you don't)
char const * cs = s.c_str();
Use sprintf, or snprintf. This function works similar to printf but instead of standard output, the output will go to char array you specified. For example:
char buffer[32];
snprintf(buffer, sizeof(buffer), "1%d:%d", lapcounter, seconds);
to_string is used like this:
#include <iostream>
#include <string>
int main()
{
int lapcounter = 23;
std::string str("1");
str.append(std::to_string(lapcounter ));
str.append(":seconds");
std::cout << str << std::endl;
}
prints
123:seconds
if you really need a char array you get that from ss.c_str()

c++ - properly writing std::string to binary file [duplicate]

This question already has answers here:
How to write std::string to file?
(4 answers)
Closed 2 months ago.
I am trying to get strings from cin and than write it to binary file.
I've read that writing pure string won't work, so I tried to convert it to char*.
The following code writes it ok (...probably), but only the first 8 chars, so the output in file is incomplete.
std::string nick, ip, port;
std::cout << "IP: ";
std::cin >> ip;
std::cout << "port: ";
std::cin >> port;
ofstream file1("lastServers.bin", ios::out | ios::binary);
if (file1.good())
{
const char* p_IP = ip.c_str();
const char* p_PORT = port.c_str();
int length = sizeof(&p_IP)+sizeof(&p_PORT);
char* tmp1 = new char[length];
int index = 0;
memcpy((tmp1 + index), p_IP, sizeof(&p_IP));
index = index + sizeof(&p_IP);
memcpy((tmp1 + index), p_PORT, sizeof(&p_PORT));
file1.write(tmp1, length);
file1.close();
delete[] tmp1;
}
else
{
std::cout << "file error write" << endl;
}
Thanks in advance for any help :)
Your code can be written as
ofstream file1("lastServers.bin", ios::out | ios::binary);
if (file1.good()) {
file1.write(ip.c_str(), ip.size());
file1.write(port.c_str(), port.size());
file1.close();
}
else {
std::cout << "file error write" << endl;
}
string::c_str() returns a const pointer to the text in the string.
string::size() returns the number of characters in the string.
You don't need to concatenate the data before writing to the file, writing one then the other has the same result.
If you wanted to write C type code rather than C++, you can use strlen(p_IP) to get the length of the IP string rather than using sizeof.
The sizeof operator gives you the size of the class instance, i.e. the size of the object BUT the string object's size is never affected by the size of the string it manages.
In C++, objects that manage something (think strings managing characters, containers managing their contents, etc.) usually have a method to determine the size of what they're managing. For std::string and other STL containers that method is size().
Note that writing these strings in this format means you can't tell where one string ends and another one starts. Two options to consider are using a terminating character that you know won't appear in any strings, or writing the length of the string to the file before the text of the string itself. I won't elaborate here as it was not asked in the original question.
sizeof returns you the size of the string object in the memory, not the length of the string itself. Specifically, sizeof(&p_IP) returns the size of the pointer to p_IP, which is always 4 bytes on a 32-bit system. Your variable length simply does not compute to the correct value. To get the length of a char*, use strlen.

How to manipulate character string being pointed to

I'm sure this is an easy question for most but I'm having trouble trying to figure out why I can't manipulate this sting and better yet how I should go about doing it. So for example we have:
char *str1="Hello World";
All I want to do is manipulate the string that is being pointed to by 'str1'. For example, as shown below, I could output the string and see the original. Then I could add a null character in there and shorten it.
cout << str1 << '\n';
str1[5] = '\0';
cout << str1;
I've also tried:
cout << str1 << '\n';
*(str1+4) = '\0';
cout << str1;
Either way I'm hoping to see something like this:
Hello World
Hello
The error I'm getting in both cases is when I try to alter the string. I know it would be easier to just declare str1 as an array (char str1[] = ....) but I'm given the constraint of having to use the dreaded char *
String literals are stored in read-only memory. You cannot modify them. In fact, in modern C++, attempting to initialise str1 the way you did will give an error. It should be a const char*:
const char* str1 = "Hello World";
This makes it clear that you shouldn't be modifying the chars.
If you want a copy of the string that you can manipulate, you should make str1 an array:
char str1[] = "Hello World";
When you initialise an array with a string literal, the characters are copied into the array.
So after all of the help I've received from you all I went with first determining the length of the strings, initializing an array of the same size+1, and then iterating through the original to save it into an array. Then I was able to manipulate it as i pleased.
int someFunc(char *inpStr){
int counter = 0;
//Find the length of the input string
while(inpStr[counter]!='\0'){counter++;}
//Input initialize an array of same size
char strArray[counter+1];
//Copy whats in the char * to the array and make sure it ends with null
for(int i=0;i<=counter;i++){strArray[i]=*(inpStr+i);}
strArray[counter]='\0';
.....
return 0;
}
Thanks for all the help!
Why you cannot change the str1 has been explained aptly by Joseph. But still if you want to modify it you can use something like this:
char *str = "hello";
char *ptr = new char[strlen(str)+1];
strcpy(ptr,str);
ptr[2] = 'd';
str = ptr;
I hope this solves your problem.

C++ stringstream to char* conversion memory allocation

Can anyone explain how the following code is working and does not crash the application?
int main() {
char *tempStr = new char[5];
tempStr[0] = '\0';
string stemp = "helloworld";
stringstream sstream;
sstream.str(stemp);
cout << "len before = " << strlen(tempStr);
sstream >> tempStr;
cout << "len after = " << strlen(tempStr) << endl;
cout << tempStr << endl;
delete[] tempStr;
return 1;
}
I am getting the output as
len before = 0
len after = 10
helloworld
Did stringstream allocate memory for the extra characters in the char pointer?
Also want to know the correct way to copy data from stringstream to char* array, without exceeding the memory allocated for char*?
Did stringstream allocate memory for the extra characters in the char pointer?
No. Your code invokes undefined behavior.
Also want to know the correct way to copy data from stringstream to char* array, without exceeding the memory allocated for char*?
It is not a good idea to read into char*. Use std::string to read input from stream. But then if you still want to know for the sake of knowledge, use std::istream::read().
if ( sstream.read(tempStr, 5 ) )
{
//read succeeded
}
By the way, you can merge these two lines:
stringstream sstream;
sstream.str(stemp);
into one:
stringstream sstream(stemp);
or simply this:
stringstream sstream("helloworld"); //no need of stemp!
Hope that helps.
No. You overwrote memory, invoking undefined behavior, but nothing obvious happened, so the error went unnoticed. There is no requirement that doing something like this should trigger any kind of human-visible error or special action, thus the wording undefined behavior.
You're going to have to do it chunk by chunk, and re-allocate the char array if it runs out of space. In C++, there's little point in doing this manually. Just use std::string and be done.

invalid initializer

This code keep saying : error: invalid initializer
char * ss = "hello world";
char s[10] = ss;
std::transform(s, s + std::strlen(s), s, static_cast<int(*)(int)>(std::toupper));
How can it be fixed?
Your initializer of the array with a C string is invalid. The good news is that you do not need it at all:
char * ss = "hello world";
char s[12];
std::transform(ss, ss + std::strlen(ss)+1, s, static_cast<int(*)(int)>(std::toupper));
cerr << s << endl;
Note that I padded your s array with an extra element for the terminating zero.
char s[10] = ss;
This tries to set an array's value equal to a pointer, which doesn't make any sense. Also, ten bytes isn't enough (there's a terminating zero byte on the end of a C-style string). Try:
char s[20];
strcpy(s, ss);
Your array assignment is illegal and, in the case of your code, isn't needed in the first place.
const char * ss = "hello world";
char s[12];
std::transform(ss, ss + std::strlen(ss)+1, s, static_cast<int(*)(int)>(std::toupper));
You can't assign a pointer to an array because you can't assign anything to arrays but initialiser lists. You need to copy the characters from ss to s. Also, an array of size 10 is too small to hold "hello world". Example:
char * ss = "hello world";
char s[12] = {}; // fill s with 0s
strncpy(s, ss, 11); // copy characters from ss to s
Alternatively, you could do
char s[] = "hello world"; // create an array on the stack, and fill it with
// "hello world". Note that we left out the size because
// the compiler can tell how big to make it
// this also lets us operate on the array instead of
// having to make a copy
std::transform(s, s + sizeof(s) - 1, s, static_cast<int(*)(int)>(std::toupper));