Jump to content
  • Advertisement
Sign in to follow this  
dacosi

126 or 127 characters?

This topic is 4106 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
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.

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][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.

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
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?

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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!