In C, there is no concept of a string as an object. Instead, they are represented as arrays of individual characters with a null-terminator (or 0) denoting the end.

strcpy uses this fact to work. Starting at the pointer passed for the src, it steps character-by-character until it reaches a null-terminator, copying memory over at each step. A common implementation that most libraries use:

char *strcpy( char *dest, char *src ) {
// strcpy returns a pointer to the written string, so save a version
char *orig_dest = dest;
// while the character at src isn't 0, copy the character over to dest and increase
// the write location
while( *dest++ = *src++ );
return orig_dest;
}

However, like the quote at the beginning of this article, fgetln doesn't null-terminate strings, instead returning the literal byte-stream from the file (\n, \t, and all). Even worse, normally the area grabbed for line is zero'd out, making it seem like it is working as intended. As noted above, the strncpy example only works because buffer was initialized to all 0's in its declaration. In fact, there is a bug with the strncpy example. Take the following file:

However, this quirk can also be an advantage. If you have a long string that you want to truncate, this can easily be done by simply throwing a null-terminator in the position you want to truncate:

char some_long_string[1024] = //some string
some_long_string[80] = 0;

Another interesting quirk: characters in C are integers, with their value representing an ASCII value. This mean, if you wanted to write a cipher that increased every letter by one (e.g., "abc" becomes "bcd"), it can be done easily:

for( int i = 0; i < strlen(s); i++ ) {
s[i]++; //increase the value of the character at index i by 1
}