The output of the following code confuses me:
const std::string str = "Modern C++";
std::string s1 {"Modern C++", 3};
std::string s2 {str, 3};
std::cout << "S1: " << s1 << "\n";
std::cout << "S2: " << s2 << "\n";
output:
> S1: Mod
> S2: ern C++
Can anyone explain this result?
std::string is the string class from the standard C++ library. String is some other string class from some other library. It's hard to say from which library, because there are many different libraries that have their own class called String.
In order to compare two strings, we can use String's strcmp() function. The strcmp() function is a C library function used to compare two strings in a lexicographical manner. The function returns 0 if both the strings are equal or the same. The input string has to be a char array of C-style string.
A std::string_view can refer to both a C++ string or a C-string. All that std::string_view needs to store is a pointer to the character sequence and a length. std::string_view provides the same API that std::string does, so it is a perfect match for C-style string literals.
Use std::string when you need to store a value. Use const char * when you want maximum flexibility, as almost everything can be easily converted to or from one. Save this answer.
From:
https://en.cppreference.com/w/cpp/string/basic_string/basic_string
std::string s1 {"Modern C++", 3};
Uses the following constructor:
basic_string( const CharT* s,
size_type count,
const Allocator& alloc = Allocator() );
So takes 3 chars to get Mod
.
std::string s2 {str, 3};
will use the following constructor:
basic_string( const basic_string& other,
size_type pos,
const Allocator& alloc = Allocator() );
So taking the string from position 3 onwards giving : ern C++
.
One is calling string(char const*, count)
, the other string(string const&, pos)
.
One gets the first 3 characters from a buffer, the other all the characters after the 3rd one.
This is because C++ has raw character buffers and std strings. "this is not a std::string"
. "this is a std string"s
, std::string so_is="this";
.
std::string
is more than 30 years old, and it was added to the C++ language without sufficient care (unlike the STL, which went through more iterations before being added).
Its interface is honestly too rich, and you can run into stuff like this; multiple overloads that lead to confusing results.
Can anyone explain to me why is that?
That is due to std::string
having constructors which it really shouldn't (@ORR explained the details). And it shouldn't have these constructors because:
std::string
methods and existing constructors - at no extra cost (in C++11 at least), andThis is not the only case in the standard library with such undersirable (IMHO) constructors; std::vector
is (in)famous for too much constructor variety and confusing/misleading constructor semantics.
Life lessons:
Incase you want to get the same output like
Mod for s1
Mod for s2
You can use a char pointer for str e.g
char * str = "Modern C++";
std::string s1 {"Modern C++", 3};
std::string s2 {str, 3};
std::cout << "S1: " << s1 << "\n";
std::cout << "S2: " << s2 << "\n";
The output
Mod
Mod
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With