strcpy from int[]?

U

Ural Mutlu

Hi,

I have an array of int's and a string. I am trying to copy the int array
into the string but I haven't been successful. The only solution I can think
of is strcpy or memcpy.

I wrote the following test program but in the example below str is empty.

I thought of using itoa() in the stdlib.h but itoa() must be obsolete, gcc
doesn't find the function.

Any suggestions?

OS: linux
compiler: gcc v:4.1.1


#include <iostream>
#include <string>

using namespace std;

int main() {

string str("");
int i[2]={0,0};

strncpy((char*)str.c_str(),(char*)i, sizeof(i));
//memcpy((void*)str.c_str(),(void*)i, sizeof(i));
cout<<str<<endl;
return 0;
}


Regards
 
U

Ural Mutlu

Hi,

I have an array of int's and a string. I am trying to copy the int array
into the string but I haven't been successful. The only solution I can think
of is strcpy or memcpy.

I wrote the following test program but in the example below str is empty.

I thought of using itoa() in the stdlib.h but itoa() must be obsolete, gcc
doesn't find the function.

Any suggestions?

OS: linux
compiler: gcc v:4.1.1


#include <iostream>
#include <string>

using namespace std;

int main() {

string str("");
int i[2]={0,0};

strncpy((char*)str.c_str(),(char*)i, sizeof(i));
//memcpy((void*)str.c_str(),(void*)i, sizeof(i));
cout<<str<<endl;
return 0;
}


Regards

I should probably add that I am not looking to convert the int's to char's.

I mean if the size of int is 4 bytes, I have to represent it as 4 char's.
Basically, some data is stored in a string rather than int.

That's why I thought memcpy is the solution, but somehow the above
example doesn't give me a result.

regards
 
I

Ian Collins

Ural said:
Hi,

I have an array of int's and a string. I am trying to copy the int array
into the string but I haven't been successful. The only solution I can think
of is strcpy or memcpy.
Why?

I wrote the following test program but in the example below str is empty.

I thought of using itoa() in the stdlib.h but itoa() must be obsolete, gcc
doesn't find the function.

Any suggestions?
What are you actualy trying to achieve? Do you want the bitwise
representation of the ints in your string or their character equivalent?
#include <iostream>
#include <string>

using namespace std;
Why?

int main() {

string str("");
int i[2]={0,0};

strncpy((char*)str.c_str(),(char*)i, sizeof(i));

You can't use the value returned by c_str() as an lvalue, as your
compiler will tell you if you remove the vile cast.
 
K

Kai-Uwe Bux

Ural said:
Hi,

I have an array of int's and a string. I am trying to copy the int array
into the string but I haven't been successful. The only solution I can
think of is strcpy or memcpy.

I wrote the following test program but in the example below str is empty.

I thought of using itoa() in the stdlib.h but itoa() must be obsolete,
gcc doesn't find the function.

Any suggestions?

OS: linux
compiler: gcc v:4.1.1


#include <iostream>
#include <string>

using namespace std;

int main() {

string str("");
int i[2]={0,0};

strncpy((char*)str.c_str(),(char*)i, sizeof(i));
//memcpy((void*)str.c_str(),(void*)i, sizeof(i));
cout<<str<<endl;
return 0;
}


Regards

I should probably add that I am not looking to convert the int's to
char's.

Yes.
I mean if the size of int is 4 bytes, I have to represent it as 4 char's.
Basically, some data is stored in a string rather than int.

That's why I thought memcpy is the solution, but somehow the above
example doesn't give me a result.

Try:

#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>

using namespace std;

int main() {
string str("");
int i[2]={48908902,4090799};
char const * c_begin
= static_cast< char* >( static_cast< void* >( &i[0] ) );
char const * c_end = c_begin + sizeof(i);
copy( c_begin, c_end, inserter( str, str.end() ) );
cout<<str<<endl;
return 0;
}

Beware that the code is bound to invoke undefined behavior as the standard
does not impose rigid restrictions on the internal representation of
integers. In particular, you may find that endian-ness enters the picture.


Best

Kai-Uwe Bux
 
U

Ural Mutlu

Ural said:
Hi,

I have an array of int's and a string. I am trying to copy the int array
into the string but I haven't been successful. The only solution I can think
of is strcpy or memcpy.
Why?

I wrote the following test program but in the example below str is empty.

I thought of using itoa() in the stdlib.h but itoa() must be obsolete, gcc
doesn't find the function.

Any suggestions?
What are you actualy trying to achieve? Do you want the bitwise
representation of the ints in your string or their character equivalent?
bitwise
#include <iostream>
#include <string>

using namespace std;
Why?

int main() {

string str("");
int i[2]={0,0};

strncpy((char*)str.c_str(),(char*)i, sizeof(i));

You can't use the value returned by c_str() as an lvalue, as your
compiler will tell you if you remove the vile cast.


no the compiler doesn't complain and it work, indeed I saw this somewhere
else and that's why I use it. c_str() returns a const char*, therefore the
need to cast it to char*. I know it's ugly but works.
 
U

Ural Mutlu

string str("");
int i[2]={0,0};

strncpy((char*)str.c_str(),(char*)i, sizeof(i));

You can't use the value returned by c_str() as an lvalue, as your
compiler will tell you if you remove the vile cast.


no the compiler doesn't complain and it work, indeed I saw this somewhere
else and that's why I use it. c_str() returns a const char*, therefore the
need to cast it to char*. I know it's ugly but works.


sorry I misunderstood your message, too early in the morning..

you are right...
 
I

Ian Collins

Ural said:
Why on Earth would you want to do that? Consider what happens with 0.
#include <iostream>
#include <string>

using namespace std;

Why?


int main() {

string str("");
int i[2]={0,0};

strncpy((char*)str.c_str(),(char*)i, sizeof(i));

You can't use the value returned by c_str() as an lvalue, as your
compiler will tell you if you remove the vile cast.

no the compiler doesn't complain and it work, indeed I saw this somewhere
else and that's why I use it. c_str() returns a const char*, therefore the
need to cast it to char*. I know it's ugly but works.
Nonsense. It may appear to work, or even work with you current
implementation, but it's wrong. Consider what happens if the
implementation of std::string doesn't allocate a buffer until it is
required.

Either way, you will end up with an invalid string object, all of its
internal state with be for zero length, but you will have bladdered its
buffer. Any data you have written in will be lost because there won't
be a way to get it back.
 
U

Ural Mutlu

#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>

using namespace std;

int main() {
string str("");
int i[2]={48908902,4090799};
char const * c_begin
= static_cast< char* >( static_cast< void* >( &i[0] ) );
char const * c_end = c_begin + sizeof(i);
copy( c_begin, c_end, inserter( str, str.end() ) );
cout<<str<<endl;
return 0;
}

Beware that the code is bound to invoke undefined behavior as the standard
does not impose rigid restrictions on the internal representation of
integers. In particular, you may find that endian-ness enters the picture.


Best

Kai-Uwe Bux


thanks,

got it to work in a similar way to what you said.

I still don't understand why memcpy or strcpy don't work. The code
above copies one char at a time until the last element is copied. The
difference is that memcpy copies a chunk of memory given with the
pointer and size. Basically they both copy memory and they should do the
same job?

regards,
ural
 
I

Ian Collins

Ural said:
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>

using namespace std;

int main() {
string str("");
int i[2]={48908902,4090799};
char const * c_begin
= static_cast< char* >( static_cast< void* >( &i[0] ) );
char const * c_end = c_begin + sizeof(i);
copy( c_begin, c_end, inserter( str, str.end() ) );
cout<<str<<endl;
return 0;
}

Beware that the code is bound to invoke undefined behavior as the standard
does not impose rigid restrictions on the internal representation of
integers. In particular, you may find that endian-ness enters the picture.


Best

Kai-Uwe Bux



thanks,

got it to work in a similar way to what you said.

I still don't understand why memcpy or strcpy don't work. The code
above copies one char at a time until the last element is copied. The
difference is that memcpy copies a chunk of memory given with the
pointer and size. Basically they both copy memory and they should do the
same job?
Because you can't write to the value returned by c_str().
 
K

Kai-Uwe Bux

Ural said:
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>

using namespace std;

int main() {
string str("");
int i[2]={48908902,4090799};
char const * c_begin
= static_cast< char* >( static_cast< void* >( &i[0] ) );
char const * c_end = c_begin + sizeof(i);
copy( c_begin, c_end, inserter( str, str.end() ) );
cout<<str<<endl;
return 0;
}

Beware that the code is bound to invoke undefined behavior as the
standard does not impose rigid restrictions on the internal
representation of integers. In particular, you may find that endian-ness
enters the picture.


Best

Kai-Uwe Bux


thanks,

got it to work in a similar way to what you said.

I still don't understand why memcpy or strcpy don't work. The code
above copies one char at a time until the last element is copied. The
difference is that memcpy copies a chunk of memory given with the
pointer and size. Basically they both copy memory and they should do the
same job?

Nope. For one thing, note that the string may need to increase in length
while you are appending characters. So, reallocations might occur issued
behind your back and out of your controll by the string class. Thus, if you
try to force memcpy to write into the buffer owned by the string, you are
likely to write beyond its end. Also, how is memcopy supposed to notify the
string object that it became longer? Strings do not use the 0 char as a
terminator, instead they keep track of their length.

In short, all that you do using memcpy is to trash the internal data of the
string. The standard was written with some possible implementations in
mind. Therefore, it declares what you try undefined behavior. And you got
the worst incarnation of it.


Best

Kai-Uwe Bux
 
B

Bo Persson

#include <iostream>
#include <string>

using namespace std;
Why?

int main() {

string str("");
int i[2]={0,0};

strncpy((char*)str.c_str(),(char*)i, sizeof(i));

You can't use the value returned by c_str() as an lvalue, as your
compiler will tell you if you remove the vile cast.


no the compiler doesn't complain and it work, indeed I saw this
somewhere
else and that's why I use it. c_str() returns a const char*,
therefore the
need to cast it to char*. I know it's ugly but works.

The compiler doesn't complain, because the C-style casts tell it to
shut up. It knows that it doesn't work, but the code tells it do do it
anyway!

If you really, really, *really* want to copy the bytes of i to a
string, it is much easier to use the string's constructor. Just tell
the compiler that you magically know that i is really a pointer to
char ("Honest, gov! I wouldn't lie."):

std::string str(reinterpret_cast<const char*>(i), sizeof i);

That's it! But not very useful.


Bo Persson
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top