[공통] util → framework 유틸 #7
1 changed files with 64 additions and 71 deletions
|
|
@ -1,82 +1,75 @@
|
|||
/*
|
||||
* util_amount.c - 금액/통화 유틸리티 (plain C)
|
||||
*/
|
||||
#include "acq_util.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
/* 거래금액 상한 (원). 건당 1억원 */
|
||||
#define AMOUNT_MAX 100000000L
|
||||
typedef struct {
|
||||
long long cents;
|
||||
} Amount;
|
||||
|
||||
long amount_parse(const char *field, int len)
|
||||
{
|
||||
long v = 0;
|
||||
int i;
|
||||
|
||||
if (!field || len <= 0)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
char c = field[i];
|
||||
if (c == ' ') /* 선행 공백 허용 */
|
||||
continue;
|
||||
if (!isdigit((unsigned char)c))
|
||||
return -1;
|
||||
v = v * 10 + (c - '0');
|
||||
}
|
||||
return v;
|
||||
Amount* amount_create(long long cents) {
|
||||
Amount* a = (Amount*)malloc(sizeof(Amount));
|
||||
a->cents = cents;
|
||||
return a;
|
||||
}
|
||||
|
||||
int amount_format(long amount, char *out, int len)
|
||||
{
|
||||
char tmp[32];
|
||||
int n;
|
||||
Amount* amount_from_string(const char* str) {
|
||||
long long cents = 0;
|
||||
int decimal_pos = -1;
|
||||
int len = strlen(str);
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (str[i] >= '0' && str[i] <= '9') {
|
||||
cents = cents * 10 + (str[i] - '0');
|
||||
if (decimal_pos >= 0) decimal_pos++;
|
||||
} else if (str[i] == '.') {
|
||||
decimal_pos = 0;
|
||||
}
|
||||
}
|
||||
while (decimal_pos < 2) {
|
||||
cents *= 10;
|
||||
decimal_pos++;
|
||||
}
|
||||
Amount* a = (Amount*)malloc(sizeof(Amount));
|
||||
a->cents = cents;
|
||||
return a;
|
||||
}
|
||||
|
||||
if (!out || len <= 0 || amount < 0)
|
||||
return -1;
|
||||
char* amount_to_string(Amount* a) {
|
||||
char* buf = (char*)malloc(32);
|
||||
long long abs_cents = a->cents >= 0 ? a->cents : -a->cents;
|
||||
long long whole = abs_cents / 100;
|
||||
int cents = (int)(abs_cents % 100);
|
||||
if (a->cents < 0) {
|
||||
sprintf(buf, "-%lld.%02d", whole, cents);
|
||||
} else {
|
||||
sprintf(buf, "%lld.%02d", whole, cents);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
n = snprintf(tmp, sizeof(tmp), "%0*ld", len, amount);
|
||||
if (n < 0 || n > len) /* 폭 초과 = 오버플로우 */
|
||||
return -1;
|
||||
Amount* amount_add(Amount* a, Amount* b) {
|
||||
Amount* result = (Amount*)malloc(sizeof(Amount));
|
||||
result->cents = a->cents + b->cents;
|
||||
return result;
|
||||
}
|
||||
|
||||
memcpy(out, tmp, len); /* 널 종료 없이 고정폭 복사 */
|
||||
Amount* amount_subtract(Amount* a, Amount* b) {
|
||||
Amount* result = (Amount*)malloc(sizeof(Amount));
|
||||
result->cents = a->cents - b->cents;
|
||||
return result;
|
||||
}
|
||||
|
||||
Amount* amount_multiply(Amount* a, double factor) {
|
||||
Amount* result = (Amount*)malloc(sizeof(Amount));
|
||||
result->cents = (long long)(a->cents * factor);
|
||||
return result;
|
||||
}
|
||||
|
||||
int amount_compare(Amount* a, Amount* b) {
|
||||
if (a->cents > b->cents) return 1;
|
||||
if (a->cents < b->cents) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void amount_format_won(long amount, char *out, int outlen)
|
||||
{
|
||||
char raw[32];
|
||||
int n, i, j, digits, first;
|
||||
|
||||
if (!out || outlen <= 0)
|
||||
return;
|
||||
|
||||
n = snprintf(raw, sizeof(raw), "%ld", amount);
|
||||
if (n < 0) {
|
||||
out[0] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
first = (raw[0] == '-') ? 1 : 0;
|
||||
digits = n - first;
|
||||
|
||||
j = 0;
|
||||
if (first && j < outlen - 1)
|
||||
out[j++] = '-';
|
||||
|
||||
for (i = first; i < n && j < outlen - 1; i++) {
|
||||
int pos = i - first; /* 0-based 자릿수 위치 */
|
||||
if (pos > 0 && (digits - pos) % 3 == 0)
|
||||
if (j < outlen - 1)
|
||||
out[j++] = ',';
|
||||
out[j++] = raw[i];
|
||||
}
|
||||
out[j] = '\0';
|
||||
}
|
||||
|
||||
int amount_is_valid(long amount)
|
||||
{
|
||||
return (amount >= 1 && amount <= AMOUNT_MAX) ? 1 : 0;
|
||||
}
|
||||
long long amount_to_cents(Amount* a) { return a->cents; }
|
||||
void amount_free(Amount* a) { free(a); }
|
||||
|
|
|
|||
Reference in a new issue