126 or 127 characters?

Started by
5 comments, last by rip-off 16 years, 7 months ago
I have got a question here: How many characters can you TYPE safely in the code below? int main() { char buffer[128]; char *result; while (!feof(stdin)) { result = fgets( &buffer[0],128,stdin); if (result!=NULL) { buffer[strlen(buffer)-1] = ’\0’; printf( "String is >%s<\n",&buffer[0] ); } } return 0; } Safe as in there will be no loss of characters. I got the answer as 126 but my friends told me it was 127. Your opinion? Cheers, dacosi.
Advertisement
127. The char array is of static length 128, all char strings need a null terminator at the end, 128-1 = 127.

strlen returns the length of the string without the null terminator.

Steven Yau
[Blog] [Portfolio]

That is what I thought first. But when I key in 127 characters, the 127th character is gone. Strange,no? When I enter 128 characters, the 127th is missing and 128 appear in the next String>a<.
Quote:Original post by yaustar
-snip-
strlen returns the length of the string without the null terminator.



buffer[strlen(buffer)-1] = '\0';
should probably be
buffer[strlen(buffer)] = '\0';

or better yet.

//buffer[...]

as fgets should terminate the buffer for you iirc.

Quote:Original post by dacosi
That is what I thought first. But when I key in 127 characters, the 127th character is gone. Strange,no? When I enter 128 characters, the 127th is missing and 128 appear in the next String>a<.


as it is right now the code will always replace the last character with '\0'; (Thus effectivly removing it)

lets say you have a buffer of size 4 instead (for simplicity)
if you input 3 characters "abc"

result = fgets(&buffer[0],4,stdin); would put [a][c][\0] in the buffer.
strlen(buffer) would return 3, thus buffer[strlen(buffer)-1]='\0' would change buffer[2] to '\0' making the end result [a][\0][\0]

if you instead enter "abcd" it should put [a][c][\0] into the buffer anyway. (fgets reads at most num-1 characters and terminates the buffer) leaving [d] in stdin to be read upon the next iteration.
[size="1"]I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!
char buffer[128];
buffer[strlen(buffer)-1] = ’\0’;

Those are the two lines in question.
If you enter 10 characters, then 0-9 will be what you entered, and then the 9th character will be replaced with the null character (because strlen(buffer) will equal 10, and therefore 10-1 = 9 -- so buffer[9] will be overwritten -- which isn't what you want).

In the case where you enter 127 characters, the 127th character is erased (hence why you get 126).

Entering 128 should be undefined, because it won't fit in the buffer.

It should be...

buffer[min(strlen(buffer), 127)] = '\0';

Which makes the max amount of characters you can enter that won't be overwritten 127. (0-126 in the buffer).
Regarding what visage said, I have tried 10 characters ( same array of 128 elements ). All 10 characters are printed out with no problems. What's going on?
My C code is rusty, but according to here fgets() will NUL terminate the string.

Quote:
A null character is automatically appended in str after the characters read to signal the end of the C string.


In general, the code "buffer[ min(strlen(buffer),sizeof(buffer)-1) ] = '\0';" is dangerous. It is clearly trying to limit the maximum length of the string to the bounds of the array. However, by using strlen on the buffer you may already have tried a read which could walk off the edge of your processes address space and crash.

Instead, you can simply set "buffer[sizeof(buffer)-1] = '\0';". If the string read ended before that then it is fine as the string is already NUL terminated, the extra NUL does no harm.


Note: using sizeof(buffer) is correct and more maintainable than constants littered through the code (in my opinion) for local char arrays. Note that it will not work if the buffer variable is a pointer (or an array passed as a parameter, these also decay to pointers), or the type is not char (you would have to divide sizeof() by the sizeof() array elements in that case).

This topic is closed to new replies.

Advertisement