This does not happen by magic. You have in your code:
for (i = 0; i <= strlen(line); i++)
^^
The loop index i runs till strlen(line) and at this index there is a nul character in the character array and this gets copied as well. As a result your end result has nul character at the desired index.
If you had
for (i = 0; i < strlen(line); i++)
^^
then you had to put the nul character manually as:
for (i = 0; i < strlen(line); i++)
{
if ( line[i] != ' ' )
{
non_spaced[j] = line[i];
j++;
}
}
// put nul character
line[j] = 0;
Answer from codaddict on Stack OverflowThis does not happen by magic. You have in your code:
for (i = 0; i <= strlen(line); i++)
^^
The loop index i runs till strlen(line) and at this index there is a nul character in the character array and this gets copied as well. As a result your end result has nul character at the desired index.
If you had
for (i = 0; i < strlen(line); i++)
^^
then you had to put the nul character manually as:
for (i = 0; i < strlen(line); i++)
{
if ( line[i] != ' ' )
{
non_spaced[j] = line[i];
j++;
}
}
// put nul character
line[j] = 0;
Others have answered your question already, but here is a faster, and perhaps clearer version of the same code:
void line_remove_spaces (char* line)
{
char* non_spaced = line;
while(*line != '\0')
{
if(*line != ' ')
{
*non_spaced = *line;
non_spaced++;
}
line++;
}
*non_spaced = '\0';
}
Why is a null character at the end of a string important
c - Array of char* should end at '\0' or "\0"? - Stack Overflow
Passing a pointer to indicate the end of a string?
Why are strings in C++ usually terminated with '\0'? - Stack Overflow
Videos
I get that it marks the end of the string, but if I have the size with me when I declared the string what is the use of it. Plus if it’s so important why don’t int arrays have a null char at the end. The only reason I can think of is to output it into the terminal without going over the limit but I’m not sure if that’s the only reason or if it’s even a right reason
I would end it with NULL. Why? Because you can't do either of these:
array[index] == '\0'
array[index] == "\0"
The first one is comparing a char * to a char, which is not what you want. You would have to do this:
array[index][0] == '\0'
The second one doesn't even work. You're comparing a char * to a char *, yes, but this comparison is meaningless. It passes if the two pointers point to the same piece of memory. You can't use == to compare two strings, you have to use the strcmp() function, because C has no built-in support for strings outside of a few (and I mean few) syntactic niceties. Whereas the following:
array[index] == NULL
Works just fine and conveys your point.
According to the C99 spec,
NULLexpands to a null pointer constant, which is not required to be, but typically is of typevoid *'\0'is a character constant; character constants are of typeint, so it's equivalen to plain0"\0"is a null-terminated string literal and equivalent to the compound literal(char [2]){ 0, 0 }
NULL, '\0' and 0 are all null pointer constants, so they'll all yield null pointers on conversion, whereas "\0" yields a non-null char * (which should be treated as const as modification is undefined); as this pointer may be different for each occurence of the literal, it can't be used as sentinel value.
Although you may use any integer constant expression of value 0 as a null pointer constant (eg '\0' or sizeof foo - sizeof foo + (int)0.0), you should use NULL to make your intentions clear.
Strings are correctly passed to printf() as a char * to the first character of the string. Normally, printf() goes until it finds a null byte. Is there a way to supersede that normal search for the null byte, and feed a pointer to the last character in printf?
The title of your question references C strings. C++ std::string objects are handled differently than standard C strings. \0 is important when using C strings, and when I use the term string in this answer, I'm referring to standard C strings.
\0 acts as a string terminator in C. It is known as the null character, or NUL, and standard C strings are null-terminated. This terminator signals code that processes strings - standard libraries but also your own code - where the end of a string is. A good example is strlen which returns the length of a string: strlen works using the assumption that it operates on strings that are terminated using \0.
When you declare a constant string with:
const char *str = "JustAString";
then the \0 is appended automatically for you. In other cases, where you'll be managing a non-constant string as with your array example, you'll sometimes need to deal with it yourself. The docs for strncpy, which is used in your example, are a good illustration: strncpy copies over the null terminator character except in the case where the specified length is reached before the entire string is copied. Hence you'll often see strncpy combined with the possibly redundant assignment of a null terminator. strlcpy and strcpy_s were designed to address the potential problems that arise from neglecting to handle this case.
In your particular example, array[s.size()] = '\0'; is one such redundancy: since array is of size s.size() + 1, and strncpy is copying s.size() characters, the function will append the \0.
The documentation for standard C string utilities will indicate when you'll need to be careful to include such a null terminator. But read the documentation carefully: as with strncpy the details are easily overlooked, leading to potential buffer overflows.
Why are strings in C++ usually terminated with
'\0'?
Note that C++ Strings and C strings are not the same.
In C++ string refers to std::string which is a template class and provides a lot of intuitive functions to handle the string.
Note that C++ std::string are not \0 terminated, but the class provides functions to fetch the underlying string data as \0 terminated c-style string.
In C a string is collection of characters. This collection usually ends with a \0.
Unless a special character like \0 is used there would be no way of knowing when a string ends.
It is also aptly known as the string null terminator.
Ofcourse, there could be other ways of bookkeeping to track the length of the string, but using a special character has two straight advantages:
- It is more intuitive and
- There are no additional overheads
Note that \0 is needed because most of Standard C library functions operate on strings assuming they are \0 terminated.
For example:
While using printf() if you have an string which is not \0terminated then printf() keeps writing characters to stdout until a \0 is encountered, in short it might even print garbage.
Why should we use
'\0'here?
There are two scenarios when you do not need to \0 terminate a string:
- In any usage if you are explicitly bookkeeping length of the string and
- If you are using some standard library api will implicitly add a
\0to strings.
In your case you already have the second scenario working for you.
array[s.size()] = '\0';
The above code statement is redundant in your example.
For your example using strncpy() makes it useless. strncpy() copies s.size() characters to your array, Note that it appends a null termination if there is any space left after copying the strings. Since arrayis of size s.size() + 1 a \0 is automagically added.
Stupid Doubt maybe but, still one that makes me wanna rage quit it, can someone please tell me why is there a null character at the end of a string, but not at the end of a usual integer array? like why is a char array special and needs a char to let it know of the end of it. or why the usual array is smarter in knowing where it ends. Thanks in advance
All strings inherently have ‘\0’ at the end to know when the end of the string is.
However, arrays don’t have anything like this. You can keep accessing indexes to infinity and it’ll output something.
So I’m wondering, exactly why are null terminators needed in strings if nothing similar like is applied to c++ arrays?
What’s the benefit?
TLDR: why are null terminators needed in strings but there’s nothing to signify the end of an array?