What is the correct/best/simplest way to convert a c-style string to a std::string.
The conversion should accept a max_length, and terminate the string at the first \0 char, if this occur before max_length charter.
What is the correct/best/simplest way to convert a c-style string to a std::string.
The conversion should accept a max_length, and terminate the string at the first \0 char, if this occur before max_length charter.
 
    
    This page on string::string gives two potential constructors that would do what you want:
string ( const char * s, size_t n );
string ( const string& str, size_t pos, size_t n = npos );
Example:
#include<cstdlib>
#include<cstring>
#include<string>
#include<iostream>
using namespace std;
int main(){
    char* p= (char*)calloc(30, sizeof(char));
    strcpy(p, "Hello world");
    string s(p, 15);
    cout << s.size() << ":[" << s << "]" << endl;
    string t(p, 0, 15);
    cout << t.size() << ":[" << t << "]" << endl;
    free(p);
    return 0;
}
Output:
15:[Hello world]
11:[Hello world]
The first form considers p to be a simple array, and so will create (in our case) a string of length 15, which however prints as a 11-character null-terminated string with cout << .... Probably not what you're looking for.
The second form will implicitly convert the char* to a string, and then keep the maximum between its length and the n you specify. I think this is the simplest solution, in terms of what you have to write.
 
    
    std::string str(c_str, strnlen(c_str, max_length));
At Christian Rau's request:
strnlen is specified in POSIX.1-2008 and available in GNU's glibc and the Microsoft run-time library.  It is not yet found in some other systems; you may fall back to Gnulib's substitute.
std::string the_string(c_string);
if(the_string.size() > max_length)
    the_string.resize(max_length);
 
    
    This is actually trickier than it looks, because you can't call strlen
unless the string is actually nul terminated.  In fact, without some
additional constraints, the problem practically requires inventing a new
function, a version of strlen which never goes beyond the a certain
length.  However:
If the buffer containing the c-style string is guaranteed to be at least
max_length char's (although perhaps with a '\0' before the end), 
then you can use the address-length constructor of std::string, and
trim afterwards:
std::string result( c_string, max_length );
result.erase( std::find( result.begin(), result.end(), '\0' ), result.end() );
and if you know that c_string is a nul terminated string (but perhaps
longer than max_length, you can use strlen:
std::string result( c_string, std::min( strlen( c_string ), max_length ) );
 
    
    There is a constructor accepting two pointer parameters, so the code is simply
 std::string cppstr(cstr, cstr + min(max_length, strlen(cstr)));
this is also going to be as efficient as std::string cppstr(cstr) if the length is smaller than max_length.
 
    
    What you want is this constructor:
std::string ( const string& str, size_t pos, size_t n = npos ), passing pos as 0. Your const char* c-style string will get implicitly cast to const string for the first parameter.
const char *c_style = "012abd";
std::string cpp_style = std::string(c_style, 0, 10);
UPDATE: removed the "new" from the cpp_style initialization
