When n == INT_MIN, do not use a = -n as that is undefined behavior (UB) since -n overflows int math.
Using a = n%10 will result in some value [-9 ... 0] since n < 0. No need to negate a before using it to print the digit, just subtract.
int n = INT_MIN;
int a = n%10;
putchar('0' - a);
To print the entire int, note that there are more negative values [INT_MIN ... -1] then positive ones [1 ... INT_MAX]*1. Instead of negating negative numbers to positives (and have UB with INT_MIN), negate positive ones to the negative side.
#include <limits.h>
#include <stdio.h>
...
int n = {some value from INT_MIN to INT_MAX};
int a = n < 0 ? n : -n;
char buf[21];
char *p = buf + sizeof buf - 1;
*p = '\0';
do {
p--;
*p = '0' - a%10;
a /= 10;
} while (a);
if (n < 0) {
*--p = '-';
}
puts(p);
This approach works even if instead of int, we used long long or intmax_t. We just need to adjust the buffer length. char buf[21] big enough for 64-bit integers.
*1 With the common 2's complement integer encoding, there is always one more negative. With the rare 1s' complement and sign-magnitude encoding, likely to be dropped in C2x, there are the same. Of course with those there may be a +0 and -0, yet let us leave that for historic programming.