tags:

views:

218

answers:

11
messageBuffer[0] = 1;
messageBuffer[1] = 0;
for (int i = 2; i < (userName.size() + 2); i++)
{
    messageBuffer[i] = userName[(i - 2)];
}

userName is a string. I was just wondering if there is already a function that exists that I haven't found yet. I have tried looking on cpluscplus but nothing that I see. Thanks for all the help guys =) I really appreiciate it. This site is awesome!

+3  A: 
strcpy(messageBuffer + 2, userName.c_str());

standard disclaimers about making sure you have enough memory apply

messageBuffer should be 3 characters bigger than the string (one for \0)

a bit of reference about the function here

cobbal
+2  A: 

Yes, you can use strcpy, memcpy, memmove or std::copy to do this. Just pass the address of messageBuffer[2] as the destination. strcpy( &messageBuffer[2], userName.begin() );

Evän Vrooksövich
+4  A: 

strncpy

EDIT: See @jaif answer for "C++" way.

aJ
And then do what with it? How can the highest repped answer be one which suggests a function that doesn't take a `std::string` as a parameter?
jalf
Then copy the required characters. :) @jaif, though std::copy suits perfectly it is the tendency of using C library specially when it comes to manipulating "String".
aJ
+1  A: 

Use strncpy

Naveen
A: 

What about using strcpy (or strncpy to prevent buffer overflows)?
Make sure the length of messageBuffer allows copying userName and just
strcpy(messageBuffer + 2, userName);

Traveling Tech Guy
+1  A: 

Use strncpy() for ANSI strings (char*), wcsncpy() for Unicode (wchar_t*) strings.

sharptooth
+1  A: 

You have two options, the unsafe and the safe way.

Unsafe:

// bad idea, string lengths are not checked and if src is longer than 
// memory available for dest, you will stomp over random memory
strcpy(dest, src);

Safer:

// Much safer, you can specify how many characters to copy (lesser of src length and
// dest length - 1 and add a null terminator '\0' to dest if the string was truncated).
strncpy(dest, src, num_characters);
Matt
Your strncpy line has a flaw. If dest is not big enough, then sure - there will be no buffer overflows. However: dest will not be nul terminated. (Do dest[sizeof dest - 1] = 0; if 'dest' is an array.)
nos
That's why the comment above the code specifies it should be the smaller of src length and dest length - 1
Matt
Edited to clarify adding the null terminator, that's what I get for using moble devices...code blocks get truncated and I have to go on memory from what was included.
Matt
+3  A: 

Use strcpy and check the buffer size by hand.

strncpy is a little safer, but dangerous in other way. If the buffer is too small, strncpy does not terminate the string with \0 which will cause an error somewhere else in the program.

If you want to use strncpy, then be sure to verify that the output is \0-terminated. Usually when people use strncpy, they forget to do this which is why I recommend strcpy. C and C++ programmers can usually spot the missing buffer size check when using strcpy.

hrnt
+2  A: 

If possible, use a std::vector with std::copy

std::vector<char> messageBuffer;
messageBuffer.reserve(userName.size() + 2); // optional
messageBuffer.push_back(1);
messageBuffer.push_back(0);
std::copy(userName.begin(), userName.end(), std::back_inserter(messageBuffer));
theC_API(&messageBuffer[0]);

Maybe not the fastest, but no chance of miscalculations.

stefaanv
Why not use the string with `std::copy`?
jalf
@jalf: I'm sorry, but I don't understand your question. I showed how you can put a string in a byte-buffer using vector and copy. I take the string as the source of copy.
stefaanv
A: 

Better way by using vector is

std::vector<char> messageBuffer;
messageBuffer.resize(userName.size()+2);
strcpy(&messageBuffer[0],usernamr.c_str());
std::copy(userName.begin(), userName.end(), std::back_inserter(messageBuffer));
theC_API(&messageBuffer[0]);
Vivek
@Vivek: you're probably showing that strcpy works with vector too. In that case, remove the std::copy line and explain this. Don't forget that this way you're depending that your calculation is always right, which is not obvious in more complex situations.
stefaanv
@Vivek: maybe explain why using a non safe C-variant with cryptic name is better than a function with a clear name and STL style. You can use "messageBuffer.resize(userName.size()+2); std::copy(userName.begin(), userName.end(), " if you don't like std::back_inserter.
stefaanv
+4  A: 

C++ strings are not guaranteed by the standard to be contiguous, which means that all the suggestions so far using strncpy are either unsafe (if they copy from something like &userName[0] or potentially inefficient (if they copy from userName.c_str(), which may imply an unnecessary copy)

The correct C++ solution is to use std::copy. Fast and safe.

std::copy(userName.begin(), userName.end(), messageBuffer+2);

As a general rule, if you find yourself messing around with C string functions in a C++ program, you are doing it wrong.

jalf
A nit: The code as shown does not null-terminate the string in messageBuffer. It should be: `*(std::copy(src.begin(), src.end(), buf)) = 0;`
Éric Malenfant
Another reason to prefer copy to strcpy is than an std::string can contain embedded nulls
Éric Malenfant
The warning about the non-contiguousness of basic_string's storage is right (in theory), but this is changed in C++0x. See [string.require] in n2960.
Éric Malenfant
std::copy() is not entirely safe. The destination must still be large enough to hold the elements being copied. This is the reason why thing's like checked iterators exist in the STL shipped with recent versions of MSVC++ (see http://msdn.microsoft.com/en-us/library/aa985965%28VS.80%29.aspx for details).
Void
BTW, I'm not arguing against using std::copy(). I happen to prefer it to the C library counterparts, as well.
Void
@Void: Of course the destination buffer has to be big enough. That's true no matter how you copy.
jalf
@jalf: My point was that your "Fast and safe" statement is not entirely correct with respect to safety. Yes, std::copy() is safe in terms of copying potentially discontiguous strings, but only if the destination is large enough; unfortunately there is no standard way to tell std::copy() how large the destination is.
Void
+1 For the warning about the non-contiguousness of basic_string's storage
fnieto