Hi,
In C, the only way you can check if a string is null-terminated is if you know the size of the array that it's in. If you know the array is, say, N
elements long, you can just write a loop:
bool is_null_terminated = false;
for(size_t i=0; i<N; i++)
if (arr[i] == 0)
is_null_terminated = true;
If you don't know the size of the array it's in, then any element access you make might turn out to be undefined behaviour.
But luckily, we never actually get strings from a user directly (whatever that would mean) - we get them from the operating system. If we're in main()
, for instance, we are guaranteed that:
argc
is non-negative, and correctly represents the number of arguments passed to our program from the environment it's run in
argv
is in array of char*
, of length argc+1
. The last element in the array is a null pointer; all the others are valid, null-terminated C strings.
If you like, those facts are preconditions of main
being called at all. It's impossible to validate them; but that's fine, because a function is responsible for producing a sensible result only if its preconditions are true.
This is why, back in lecture 2, I mentioned that there are two "imaginary" types that a char *
could correspond to, and which might get passed around a program, and which it's the programmer's responsibility to keep track of:
a. a valid string that is null-terminated
b. a (char*
, size_t
) pair, that represents an array of known size.
If you are ever given a char*
, without a guarantee that it's one of (a) or (b), there's simply nothing you can safely do with it.
This is why fgets()
is dangerous - its prototype is
char *fgets(char *p);
The implementer of fgets
doesn't know the size of the array p
points to, and can't be sure it's null-terminated (in fact, it probably isn't). So there is literally no operation they can safely perform on p
.
Does that make sense?
cheers
Arran
ANONYMOUS wrote:
Hi Arran,
I wanted to check whether a string from user input is null terminated before passing it to strlen or other operation which could cause undefined behaviour, but I couldn't find a way to check this. Based on my understanding, checking for null terminator, I would need to know the length of the string then check whether the last character of the string is null terminator. I have read that sizeof operator operates at compile time, so this could not work a string that a user passes. If I tried to find the string length using a loop that will also rely on the null terminator at the end. I don't know any other operators/functions that could find out the length of a string. In this case, how could I make sure a user entered string is null terminated?