Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what's the difference between these two different initialization for a string in c++?

The source code

#include <iostream>
#include <string>
using namespace std;
int main(){
    std::string s{'a', 'b', '\0', 'c'};
    std::string s1="ab\0c";
    cout<<s.size()<<" "<<s<<endl;
    cout<<s1.size()<<" "<<s1<<endl;
    return 0;
}

and the output is

4 abc
2 ab

I wonder why this phenomenon occurs and are there any difference between these two types of initialization in C++? Thanks.

like image 581
Lixun Bai Avatar asked Mar 03 '17 15:03

Lixun Bai


People also ask

How strings are declared and initialized in C?

'C' language does not directly support string as a data type. Hence, to display a String in C, you need to make use of a character array. The general syntax for declaring a variable as a String in C is as follows, char string_variable_name [array_size];

Is it necessary to initialize string?

If you are talking about std::string , you don't need to "initialize" it because it is automatically initialized to the empty string in its constructor. If you mean const char * or char * , then yes, you should initialize them because by default they point to garbage. Then you may consider remove it.


1 Answers

For s you're matching the constructor that accepts an initialiser-list of characters: that's (9) in the list here. The string class lets you construct strings from arbitrary data which may include embedded NULs, as it does in this case. The initialiser list knows its own length, so the string captures all the characters.

For s1, the matching constructor is (5) in the above-linked list, which accepts a const char* - the compiler lets the array of char provided decay to such a pointer before calling that constructor, which means the constructor has no knowledge of the length of the array. Instead, it assumes you're deliberately using the ASCIIZ NUL-terminated string convention (as in "C" strings), and scans through the data to find the first NUL, considering that the terminator. Consequently, only 2 characters are captured in the string.

Note that you can explicitly capture 4 characters with...

std::string s1 { "ab\0c", 4};

...which matches constructor (4) in the list.

Rakete1111's comment below illustrates another, newer way to create such strings: auto s1 = "ab\0c"s;.

like image 109
Tony Delroy Avatar answered Oct 06 '22 23:10

Tony Delroy