I tried to request a few clarifications in the comment but you didn't answer, so I'm assuming you are working in an environment that conforms to SYS V x86-64 ABI.
When main is called,  argc is in rdi but it is soon overwritten by the calls to strncpy and printf itself:
main:
    sub     rsp, 40
    mov     rsi, QWORD PTR [rsi+8]
    mov     edx, 32
    mov     rdi, rsp                 ;OOOPS
    call    strncpy
    mov     rdi, rsp                 ;OOOPS
    xor     eax, eax
    call    printf
    
    xor     eax, eax
    add     rsp, 40
    ret
The code above is the compiled output of your sample program (once cleaned).
But, glibc on the SYS V x86-64 ABI doesn't synthesize argc itself (like the Windows' counterpart has to do, see GetCommandLine and similar), this value is passed as the first value on the stack when a program is created (see figure 3.9 of the ABI specifications).

So you can reach it with printf by using a %d format that skips the first k - 1 arguments, that is with %k$d where k is the number to be found.
To find k you just have to find the offset between rsp when printf is called and the address of argc.
But since argc is at the bottom of the stack when the process is created, this equals to finding the offset between rsp at the call site for printf and the initial value of rsp.
So using gdb:
gdb --args format-string test
   b _start
   r
   i r rsp
     0x7fffffffdfa0   The initial value of RSP
   b printf
   c
   i r rsp
     0x7fffffffd9d8 The value AFTER printf is called. Add 8 to find it BEFORE the call
   q
Now 0x7fffffffdfa0 - (0x7fffffffd9d8 + 8) = 0x110
0x110 bytes are 34 arguments (0x110/8 = 0x22) and since the first four arguments are in the registers, we need to skip them too, adding 4.
Finally, the count is one based and the difference inclusive so we need to add 2 to the count.
The final value is, for my example environment, 34 + 4 + 2 = 40, leading to the command:
./format-string '%40$d'