0-terminated strings not only have proven to be a rich source of bugs, they're remarkably inefficient as well [1]. Doing better was a major focus of the initial design of D.
[1] This is because of constantly scanning to get the length (which also necessitates reloading the string contents into the memory cache), and having to make copies of strings instead of just slicing them.
C programmers are expected to make the best choice based on the situation. The various choices trade off memory usage, CPU usage, source code readability, and program correctness.
Which is problematic for thread safety and depending on the source of the string (constant) may not be possible.
If available, strdupa() would be a fine way to get a suitable local copy of the string. Commonly though, the programmer knows that there will not be threads and can make the string non-constant.
I wonder how much time was wasted in early computing (maybe not wasted really) because of the fear of incompatibility that is getting smaller and smaller as computing platforms coalesce into standardized-ish things.
Watching the M1 roll out and how it doesn't seem to care much that x86 is a thing and gets along with its life has been fascinating.
String literals also have an extra 0 appended, making it transparently easy to still pass strings to C functions like printf.
I don't know if that is a typo given you normally call them "fat pointers", but they are "pretty hot and tempting".
It doesn't have the same breadth of features as, say, Python's string class, but it's ok.
1: https://www.boost.org/doc/libs/develop/libs/nowide/doc/html/...