|
-
June 23rd, 2008, 02:28 PM
#1
[RESOLVED] question about memcpy, char* and string
Hello,
I have the following code that works fine for packing and unpacking with memcpy:
#include <string>
using namespace std;
Code:
int main()
{
// PACK
char *bufptr;
char buf[12];
unsigned int data1 = 1003;
unsigned int data2 = 0;
float data3 = 90.0;
bufptr = buf;
memcpy(bufptr, &data1, 4);
bufptr+=4;
memcpy(bufptr, &data2, 4);
bufptr+=4;
memcpy(bufptr, &data3, 4);
bufptr+=4;
// UNPACK
unsigned int _data1, _data2;
float _data3;
char *temp = buf;
memcpy(&_data1, temp, 4);
temp+=4;
memcpy(&_data2, temp, 4);
temp+=4;
memcpy(&_data3, temp, 4);
temp+=4;
return 0;
}
but now I tried to add strings into the mix, and it stops working. What am I doing wrong with the strings here?
#include <string>
using namespace std;
Code:
int main()
{
// PACK
char *bufptr;
char buf[12];
unsigned int data1 = 1003;
unsigned int data2 = 0;
float data3 = 90.0;
bufptr = buf;
memcpy(bufptr, &data1, 4);
bufptr+=4;
memcpy(bufptr, &data2, 4);
bufptr+=4;
memcpy(bufptr, &data3, 4);
bufptr+=4;
string message=buf;
// UNPACK
unsigned int _data1, _data2;
float _data3;
char *temp = (char*)message.c_str();
memcpy(&_data1, temp, 4);
temp+=4;
memcpy(&_data2, temp, 4);
temp+=4;
memcpy(&_data3, temp, 4);
temp+=4;
return 0;
}
I am guessing trhe line that is wrong is this line:
char *temp = (char*)message.c_str();
Can anyone help me to make this work correctly with strings?
Thanks!!
-
June 23rd, 2008, 02:46 PM
#2
Re: question about memcpy, char* and string
 Originally Posted by lab1
Can anyone help me to make this work correctly with strings?
You could probably make it work. But it is a bad idea to keep binary data in strings because all internal functions that need to determine its size will look for a first 0 byte...
Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
Convenience and productivity tools for Microsoft Visual Studio:
FeinWindows - replacement windows manager for Visual Studio, and more...
-
June 23rd, 2008, 02:47 PM
#3
Re: question about memcpy, char* and string
There is nothing wrong with
Code:
char *temp = (char*)message.c_str();
All 'magic' happens here
Code:
string message=buf;
You initialize string object with c-string (which is 0-terminated string), so as soon as the first 0 occurs in buf, the process is stopped. I'd suggest that vector<char> is more natural type in this case.
Last edited by a1ex07; June 23rd, 2008 at 02:55 PM.
-
June 23rd, 2008, 02:55 PM
#4
Re: question about memcpy, char* and string
Hey Alex,
How can I fix this then? How do I copy a char buffer into a string?
Thanks!
-
June 23rd, 2008, 03:01 PM
#5
Re: question about memcpy, char* and string
Hey Alex,
What if I must use a string? is there any possible way to initial a string with a char buffer?
Thanks!
Curtis
-
June 23rd, 2008, 03:01 PM
#6
Re: question about memcpy, char* and string
 Originally Posted by lab1
Hey Alex,
How can I fix this then? How do I copy a char buffer into a string?
Thanks!
As has been pointed out, a string is not the right data type if your data contains embedded nulls.
-
June 23rd, 2008, 03:07 PM
#7
Re: question about memcpy, char* and string
Sorry but I think you are wrong. Here is some example code:
Code:
char buffer[14] = "testtest0test";
char buffer2[14];
string message=buffer;
char *temp = (char*)message.c_str();
memcpy(&buffer2, temp, 14);
or is this "0" not an embedded null?
Thanks
-
June 23rd, 2008, 03:10 PM
#8
Re: question about memcpy, char* and string
 Originally Posted by lab1
Hey Alex,
What if I must use a string? is there any possible way to initial a string with a char buffer?
Have you tried looking at all of the constructors that string takes?
http://www.sgi.com/tech/stl/basic_string.html
Code:
#include <string>
int main()
{
std::string s("abc123", 4);
}
In other words, a string buffer as the first parameter, and the number of bytes to use from the buffer is the second parameter.
Regards,
Paul McKenzie
-
June 23rd, 2008, 03:11 PM
#9
Re: question about memcpy, char* and string
 Originally Posted by lab1
Sorry but I think you are wrong. Here is some example code:
Code:
char buffer[14] = "testtest0test";
char buffer2[14];
string message=buffer;
char *temp = (char*)message.c_str();
memcpy(&buffer2, temp, 14);
or is this "0" not an embedded null?
Thanks
No, it's not a null.
-
June 23rd, 2008, 03:12 PM
#10
Re: question about memcpy, char* and string
You can use vector<char> instead of string
Code:
#include <vector>
int main()
{
// PACK
char buf[12];
unsigned int data1 = 1003;
unsigned int data2 = 0;
float data3 = 90.0;
bufptr = buf;
memcpy(bufptr, &data1, 4);
bufptr+=4;
memcpy(bufptr, &data2, 4);
bufptr+=4;
memcpy(bufptr, &data3, 4);
bufptr+=4;
//string message=buf;
std::vector<char> message1(12);
memcpy(&message1[0],buf,12);
// UNPACK
unsigned int _data1, _data2;
float _data3;
//char *temp = (char*)message.c_str();
char *temp = &message1[0];
memcpy(&_data1, temp, 4);
temp+=4;
memcpy(&_data2, temp, 4);
temp+=4;
memcpy(&_data3, temp, 4);
temp+=4;
return 0;
// UNPACK
You can also get rid of all char* variables and change it to :
Code:
vector<char> buffer(12);
unsigned int data1 = 1003;
unsigned int data2 = 0;
float data3 = 90.0;
// Pack
memcpy(&buffer[0], &data1, 4);
memcpy(&buffer[4], &data2, 4);
memcpy(&buffer[8], &data3, 4);
// Unpack
memcpy(&_data1, &buffer[0], 4);
memcpy(&_data2, &buffer[4], 4);
memcpy(&_data3, &buffer[8], 4);
-
June 23rd, 2008, 03:14 PM
#11
Re: question about memcpy, char* and string
 Originally Posted by GCDEF
As has been pointed out, a string is not the right data type if your data contains embedded nulls.
It can be the right data type, if you use the correct functions.
For example, std::string::append(), the correct constructor (which is not what lab1 was using), etc.
If you wish to change the data in place, then a better choice would be vector<char> (but that is also bound to change, since the standards committee has just specified that the contents of std::string are changeable and contiguous, exactly like an array).
Regards,
Paul McKenzie
-
June 23rd, 2008, 03:27 PM
#12
Re: question about memcpy, char* and string
If you have to stick to string, you can do
Code:
//...
string message;
message.resize(12);
for (int i = 0; i<12; i++)
{
message[i] = *(buf+i);
}
I'm not sure how safe it is though...
-
June 23rd, 2008, 03:34 PM
#13
Re: question about memcpy, char* and string
 Originally Posted by a1ex07
If you have to stick to string, you can do
Code:
//...
string message;
message.resize(12);
for (int i = 0; i<12; i++)
{
message[i] = *(buf+i);
}
You don't need that at all. Did you read my previous message?
Code:
string message(buf, 12);
That's all you need to do.
Regards,
Paul McKenzie
-
June 23rd, 2008, 05:26 PM
#14
Re: question about memcpy, char* and string
 Originally Posted by a1ex07
There is nothing wrong with
Code:
char *temp = (char*)message.c_str();
memcpy(&_data1, temp, 4);
temp+=4;
memcpy(&_data2, temp, 4);
temp+=4;
memcpy(&_data3, temp, 4);
temp+=4;
I'm sorry, but this is incorrect! 'c_str()' returns a const char *, casting away the const and modifying the buffer is undefined behavior.
Viggy
-
June 23rd, 2008, 06:20 PM
#15
Re: question about memcpy, char* and string
I'm sorry, but this is incorrect! 'c_str()' returns a const char *, casting away the const and modifying the buffer is undefined behavior.
The original code doesn't change buffer; removing const attribute by itself cannot cause any problem. For sure,
Code:
char const* temp = message.c_str();
looks better, but it's not an issue in this case.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|