#include <limits.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

size_t commafmt(char   *buf,            /* Buffer for formatted string  */
	int     bufsize,        /* Size of buffer               */
	long    N)              /* Number to convert            */
{
	const struct lconv *fmt_info = localeconv();
	int places = 0;
	int i, len = 1, posn = 1, sign = 1;
	char *ptr = buf + bufsize - 1;

	if (2 > bufsize)
	{
	ABORT:      *buf = '\0';
		return 0;
	}

	*ptr-- = '\0';
	--bufsize;
	if (0L > N)
	{
		sign = -1;
		N = -N;
	}

	for (; len <= bufsize; ++len, ++posn)
	{
		*ptr-- = (char)((N % 10L) + '0');
		if (0L == (N /= 10L))
			break;
		if (fmt_info->grouping[places] && 0 == (posn % fmt_info->grouping[places]))
		{
			if (fmt_info->grouping[places + 1] != '\0')
				places = fmt_info->grouping[places + 1] == CHAR_MAX ? 0 : places + 1;
			for (i = 0; fmt_info->thousands_sep[i]; i++, ++len) {
				*ptr-- = fmt_info->thousands_sep[i];
				if (len >= bufsize)
					goto ABORT;
			}
		}
		if (len >= bufsize)
			goto ABORT;
	}

	if (0 > sign)
	{
		if (len >= bufsize)
			goto ABORT;
		for (i = 0; fmt_info->negative_sign[i]; ++i) {
			*ptr-- = fmt_info->negative_sign[i];
			if (++len >= bufsize)
				goto ABORT;
		}
	}

	memmove(buf, ++ptr, len + 1);
	return (size_t)len;
}

int main() {
	char buffer[16];

	setlocale(LC_ALL, "");
	commafmt(buffer, sizeof(buffer), -12345678);

	printf("%s\n", buffer);
	return 0;
}