C-style strings are nothing but C-style arrays of type char. For example:
const char msg[]{"hi"};But there is one difference, C-style strings have one extra null character element that represents the string end. So, if the string contains 5 letters, the size of the string would be 6 with that extra null character. For example:
std::cout << std::size(msg); // should print 3C-style strings are also decayed
Similar to C-style array decay, C-style strings are also decayed when passed to function or used in expressions. In case where length information is required, function has to manually traverse the string to get its length.
Outputting C-style strings
We can print C-style strings simply by giving them to std::cout as shown below:
std::cout << msg << '\n';If you think what happens when we pass a C-style array to std::cout, we get the address of the first element because of array decay:
int arr[]{1, 2, 3};
std::cout << arr; // prints addressWhy the same thing is not happening with C-style string. So, std::cout has operator<< overload accepting array as const char*. When we provide array, the usual printing of pointer happens as there is no overload. But when we provide string, the overload triggers which prints the string until it gets the null character.
Inputting C-style strings
Consider the following:
#include <iostream>
int main(int argc, char const *argv[])
{
char input[5]{};
std::cin >> input;
std::cout << input << '\n';
return 0;
}When it compiled with compiler C++17 or prior, input decays as std::cin’s operator>> is accepting a char *. The issue with this is that the user can provide let’s say 10 characters, but the input can only store 4 elements (one for null character). Doing so will do array or buffer overflow and invoke undefined behaviors - the program may crash.
Tip
std::cinignores the leading whitespaces in the input and stops taking input when it encounters any whitespace character.
To solve this issue, in C++20, std::cin’s operator>> which accepts char* is deleted and instead it is overloaded to take c-style string by explicit reference, i.e. (instream, char (&)[N]). This bypasses the c-style string decay as there is better match than char *.
This way, operator>> has the string length information and does not store more character than the length (length - 1, as we also have to count null character). So, it solves array/buffer overflow problem.