Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does last index of string array print nothing in C?

Tags:

arrays

c

I am curious why the last element in my array of 29 size is 27, and not 28? Why is there a blank space when I try to print out the object in the 28th place? s should be the last object in the 28th place no?

#include <stdio.h>

int main(void) {
    char strArray[] = { "Jonsnow from Game of Thrones" };
    int lastElem = sizeof(strArray);

    printf("%s\n", strArray);
    printf("Size of array is: %d\n", sizeof(strArray));
    printf("first array value: %c \n", strArray[0]);
    printf("last array value: %c \n", strArray[lastElem - 1]);
    printf("last array value: %c \n", strArray[lastElem - 2]);

    return 0;
}

Output:

Jonsnow from Game of Thrones
Size of array is: 29
first array value: J
last array value:
last array value: s
like image 605
Evan Kim Avatar asked Jan 01 '23 08:01

Evan Kim


1 Answers

The last byte in a C string is the null terminator, a byte with a value of 0, also written as '\0'. strArray is a char array initialized from a C string constant, its size is exactly that of the initializer, including the null byte, hence strArray[lastElem-1] is the null byte '\0'.

Outputting a null byte with printf %c format should work fine, a null byte being written to stdout, but it is possible that your terminal ignores such bytes and produces the output you posted. You can try and redirect the output of your program to a file and examine this file with a hex editor to see if indeed it contains a null byte before the newline.

I get the same behavior on my MacBook with OS/X:

chqrlie@mba1 ~/dev/stackoverflow > ./nullbyte
Jonsnow from Game of Thrones
Size of array is: 29
first array value: J
last array value:
last array value: s

But here is the binary dump of the program's output:

chqrlie@mba1 ~/dev/stackoverflow > ./nullbyte | od -bc
0000000   112 157 156 163 156 157 167 040 146 162 157 155 040 107 141 155
           J   o   n   s   n   o   w       f   r   o   m       G   a   m
0000020   145 040 157 146 040 124 150 162 157 156 145 163 012 123 151 172
           e       o   f       T   h   r   o   n   e   s  \n   S   i   z
0000040   145 040 157 146 040 141 162 162 141 171 040 151 163 072 040 062
           e       o   f       a   r   r   a   y       i   s   :       2
0000060   071 012 146 151 162 163 164 040 141 162 162 141 171 040 166 141
           9  \n   f   i   r   s   t       a   r   r   a   y       v   a
0000100   154 165 145 072 040 112 040 012 154 141 163 164 040 141 162 162
           l   u   e   :       J      \n   l   a   s   t       a   r   r
0000120   141 171 040 166 141 154 165 145 072 040 000 040 012 154 141 163
           a   y       v   a   l   u   e   :      \0      \n   l   a   s
0000140   164 040 141 162 162 141 171 040 166 141 154 165 145 072 040 163
           t       a   r   r   a   y       v   a   l   u   e   :       s
0000160   040 012
              \n
0000162

As you can see, the fourth line does have a null byte present between spaces.

Note also that there is bug in the program: %d may be inappropriate for an argument of type size_t. The C99 format is %zu but for portability to systems with poor C99 runtime support, I would recommend this:

printf("Size of array is: %lu\n", (unsigned long)sizeof(strArray));
like image 135
chqrlie Avatar answered Jan 14 '23 10:01

chqrlie