Search code examples
cvectorchar

Store a number of one digit in a vector of char using sprintf


c[100] is a vector of char and x is a number between 1 and 9

How can I store x in a given position (n) in c

What I tried is:

sprintf(c[n], "%d", x);

but it does not work

If I write:

sprintf(&c[n], "%d", x);

it works fine. Can someone explain to me why is that? Or maybe give me another ideea to solve the problem


Solution

  • The first thing to understand is that when you declare char c[100], your program reserves 100 bytes in the stack of the current frame for c. (Remember: this means you cannot continue to use c after your function returns.)

    The main confusion comes when you try to understand the difference between c and &c. When you use c, you will get the address of the first element of c and its type is char[100]. When you use &c, you will get the address of the array c and its type is char (*)[100]. Confusingly, both values are the same.

    #include <stdio.h>
    
    int main(void) {
      char c[100];
      printf(" c: %p\n", c);  // will print (e.g.,):  c: 0x16d30b6c4
      printf("&c: %p\n", &c); // will print (e.g.,): &c: 0x16d30b6c4
      return 0;
    }
    

    With that said, when you use c[n] you get the actual char at position n of c. This is not an address; it's the actual byte value. When you use &c[n], you will get the address of position n in the array (which is the same as c + n).

    #include <stdio.h>
    
    int main(void) {
      char c[100] = "Testing";
      printf(" c: %p\n", c);        // will print (e.g.,) :  c: 0x16d30b6c4
      printf("&c: %p\n", &c);       // will print (e.g.,) : &c: 0x16d30b6c4
      printf(" c[2]: %c\n", c[2]);  // will print (always): s
      printf("&c[2]: %p\n", &c[2]); // will print (e.g.,) : &c[2]: 0x16d30b6c6
      printf("c + 2: %p\n", c + 2); // will print (e.g.,) : c + 2: 0x16d30b6c6
      return 0;
    }
    

    If you check the man page for sprintf() you will see the definition is:

    int sprintf(char *restrict s, const char *restrict format, ...);
    

    Ignoring restrict which is out of scope for this answer, the type that sprintf() expects is char * (or a pointer to a char). Per example above, the correct way to represent the address of a position of a char[] array is &array[position]. That's why your sprintf(&c[n], "%d", x); works and sprintf(c[n], "%d", x); does not.

    Finally, always consider using snprintf() which will prevent writing beyond the boundaries of your char * array. Remember to adjust the size_t n given to snprintf() if your initial char *restrict s is not the address of the first byte of the array.