Using sizeof to append a character to the end of a string form user

First, the size of char is always 1, it's defined in the specification.

Second, the size of an array is the size of the array itself, in "bytes".

That means

sizeof( charArray ) / sizeof( charArray[ 0 ] )

is equal to

20 / 1

which is equal to 20.

That is, you will always write to the twenty-first element of the array, which is out of bounds and lead to undefined behavior.

If you want to append a character to the string either use strcat to append the characters as a string (making sure you don't write out of bounds):

// Check to make sure there's space in the array, the -1 is for the terminator
if (strlen(charArray) < (sizeof charArray - 1))
{
    strcat(charArray, ")");
}

Or use strlen to get the position of the string null-terminator and overwrite it with your char (but remember to add a new null-terminator, as well as check so you don't go out of bounds):

// Get the index of the current null-terminator in the string
size_t terminator_index = strlen(charArray);

// Check to make sure there's space in the array, the -1 is for the terminator
if (terminator_index < (sizeof charArray - 1))
{
    // Can append new character
    charArray[terminator_index] = ')';

    // Add terminator
    charArray[terminator_index + 1] = '\0';
}

What you're doing wrong here is not knowing the difference between an array and a string. You have declared an array with size 20. That size will never change.

What you are looking for is the length of the string, and you get that with strlen(charArray).

A string is a sequence of printable characters terminated with the \0 character. The length of a string is the number of characters before the terminator.

This code will print 5, 20:

char arr[20] = "Hello";
printf("%zu, %zu\n", strlen(arr), sizeof(arr));

Note that this will print 3:

char arr[20] = "Hello";
printf("%zu\n", strlen(&arr[2]));

Also note that you can do things like this:

char arr[20] = "Hello\0World!\n";
printf("%zu, %zu\n", 
       strlen(&arr[0]), // Hello
       strlen(arr[strlen(&arr[0]) + 1]) // World!\n
);

This will print 5, 7. The second has a length of seven because the newline also counts. Also note that when you initialize an array, a '\0' is always appended, unless the size of the array is to small. This will declare a string without terminator:

char no_terminator[5] = "Hello";

Avoid that. It could cause you a lot of problems.

So in your case, you could do like this:

fgets( charArray, 20, stdin );

// Standard way of removing newline from a string. It's a very useful
// trick since fgets saves the newline in the string.
charArray[strcspn(charArray, "\n")] = '\0';

size_t len = strlen(charArray);
charArray[len] = ')';
charArray[len+1] = '\0';

But be careful so that len+1 never exceeds 20. If it does, you're invoking undefined behavior, which can be a real mess to debug. Also, it is wise to check if fgets returned NULL. If that's the case, you should handle the error.

If you handle this kind of input a lot, I could recommend this wrapper:

void my_readline(char *str, int n)
{
    if(fgets(str, n, stdin) == NULL) {
        perror("Error reading string");
        exit(EXIT_FAILURE);
    }
    str[strcspn(charArray, "\n")] = '\0';
}

Of course, you can customize the error handling in whatever way you want.


The expression sizeof(charArray) is twenty, and has nothing to do with the string that you have stored in it (unless that string is larger than twenty bytes, of course).

If you want to get the index of the \0 at the end of the string, you need to use strlen rather than sizeof.

For example, here's a way to do this safely:

#include <stdio.h>
#include <string.h>

int main( void ) {
    // Allow extra space for ')' and use actual size for input.

    char charArray[21];
    if (fgets(charArray, sizeof(charArray) - 1, stdin) == NULL) {
        fprintf(stderr, "Some problem occurred on input\n");
        return 1;
    }

    // Ensure terminated with newline.

    size_t len = strlen(charArray);
    if (len < 1 || charArray[len - 1] != '\n') {
        fprintf(stderr, "Input is not terminated with newline\n");
        return 1;
    }

    // Just replace newline with ')' character.

    charArray[len - 1] = ')';
    printf("%s\n", charArray);
}

By the way, if you're looking for a bullet-proof user input function in standard C, you'd be well advised to check out this one. I've used this for many years without problem.