How to copy a string into a char array in C++ with

2019-01-21 23:34发布

I want to copy a string into a char array, and not overrun the buffer.

So if I have a char array of size 5, then I want to copy a maximum of 5 bytes from a string into it.

what's the code to do that?

11条回答
甜甜的少女心
2楼-- · 2019-01-21 23:46
std::string my_string("something");
char* my_char_array = new char[5];
strncpy(my_char_array, my_string.c_str(), 4);
my_char_array[4] = '\0'; // my_char_array contains "some"

With strncpy, you can copy at most n characters from the source to the destination. However, note that if the source string is at most n chars long, the destination will not be null terminated; you must put the terminating null character into it yourself.

A char array with a length of 5 can contain at most a string of 4 characters, since the 5th must be the terminating null character. Hence in the above code, n = 4.

查看更多
男人必须洒脱
3楼-- · 2019-01-21 23:47

Update: Thought I would try to tie together some of the answers, answers which have convinced me that my own original knee-jerk strncpy response was poor.

First, as AndreyT noted in the comments to this question, truncation methods (snprintf, strlcpy, and strncpy) are often not a good solution. Its often better to check the size of the string string.size() against the buffer length and return/throw an error or resize the buffer.

If truncation is OK in your situation, IMHO, strlcpy is the best solution, being the fastest/least overhead method that ensures null termination. Unfortunately, its not in many/all standard distributions and so is not portable. If you are doing a lot of these, it maybe worth providing your own implementation, AndreyT gave an example. It runs in O(result length). Also the reference specification returns the number of bytes copied, which can assist in detecting if the source was truncated.

Other good solutions are sprintf and snprintf. They are standard, and so are portable and provide a safe null terminated result. They have more overhead than strlcpy (parsing the format string specifier and variable argument list), but unless you are doing a lot of these you probably won't notice the difference. It also runs in O(result length). snprintf is always safe and that sprintf may overflow if you get the format specifier wrong (as other have noted, format string should be "%.<N>s" not "%<N>s"). These methods also return the number of bytes copied.

A special case solution is strncpy. It runs in O(buffer length), because if it reaches the end of the src it zeros out the remainder of the buffer. Only useful if you need to zero the tail of the buffer or are confident that destination and source string lengths are the same. Also note that it is not safe in that it doesn't necessarily null terminate the string. If the source is truncated, then null will not be appended, so call in sequence with a null assignment to ensure null termination: strncpy(buffer, str.c_str(), BUFFER_LAST); buffer[BUFFER_LAST] = '\0';

查看更多
We Are One
4楼-- · 2019-01-21 23:49
std::string str = "Your string";
char buffer[5];
strncpy(buffer, str.c_str(), sizeof(buffer)); 
buffer[sizeof(buffer)-1] = '\0';

The last line is required because strncpy isn't guaranteed to NUL terminate the string (there has been a discussion about the motivation yesterday).

If you used wide strings, instead of sizeof(buffer) you'd use sizeof(buffer)/sizeof(*buffer), or, even better, a macro like

#define ARRSIZE(arr)    (sizeof(arr)/sizeof(*(arr)))
/* ... */
buffer[ARRSIZE(buffer)-1]='\0';
查看更多
▲ chillily
5楼-- · 2019-01-21 23:53

i think snprintf() is much safe and simlest

snprintf ( buffer, 100, "The half of %d is %d", 60, 60/2 );

null character is append it end automatically :)

查看更多
太酷不给撩
6楼-- · 2019-01-21 23:55

If you always have a buffer of size 5, then you could do:

std::string s = "Your string";
char buffer[5]={s[0],s[1],s[2],s[3],'\0'};

Edit: Of course, assuming that your std::string is large enough.

查看更多
走好不送
7楼-- · 2019-01-22 00:00

Some nice libc versions provide non-standard but great replacement for strcpy(3)/strncpy(3) - strlcpy(3).

If yours doesn't, the source code is freely available here from the OpenBSD repository.

查看更多
登录 后发表回答