Sign in to follow this  

126 or 127 characters?

This topic is 3741 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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<.

Share this post


Link to post
Share on other sites
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][b][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][b][\0][\0]

if you instead enter "abcd" it should put [a][b][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.

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites

This topic is 3741 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this