1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/* definiramo jezik - ZAČETEK */
#define J_0 "zero"
#define J_1 "one"
#define J_2 "two"
#define J_3 "three"
#define J_4 "four"
#define J_5 "five"
#define J_6 "six"
#define J_7 "seven"
#define J_8 "eight"
#define J_9 "nine"
#define J_10 "ten"
#define J_11 "eleven"
#define J_12 "twelve"
#define J_13 "thirteen"
#define J_14 "fourteen"
#define J_15 "fiveteen"
#define J_16 "sixteen"
#define J_17 "seventeen"
#define J_18 "eighteen"
#define J_19 "nineteen"
#define J_20 "twenty"
#define J_30 "thirty"
#define J_40 "forty"
#define J_50 "fifty"
#define J_60 "sixty"
#define J_70 "seventy"
#define J_80 "eighty"
#define J_90 "ninety"
#define J_1h "hundred"
#define J_1k "thousand"
#define J_1M "million"
#define J_1G "billion"
#define J_1T "trillion"
#define J_AND "and"
#define J_EMPTY ""
/* definiramo jezik - KONEC */
#define MX_NS_L 1337
/* angnum : size_t (število zapisanih bajtov, -1 ob propadu sveta)
* n: lluint: številka, ki naj jo zapišemo
* s: pointer to allocatanega spomina, kamor zapišemo string
* l: število bajtov allocatanega spomina za string, IZključno zadnjega '\0'
* alocirati morate vsaj en bajt več od l
* string bo mogoče avtomatsko null terminiran, vseeno ga raje dajte še sami */
char * j_enice[] = { J_EMPTY, J_1, J_2, J_3, J_4, J_5, J_6, J_7, J_8, J_9, J_10, J_11, J_12, J_13, J_14, J_15, J_16, J_17, J_18, J_19, J_20 };
char * j_power[] = { J_EMPTY, J_1k, J_1M, J_1G, J_1T };
char * j_desetice[] = { J_EMPTY, J_10, J_20, J_30, J_40, J_50, J_60, J_70, J_80, J_90 };
unsigned long long int na(unsigned long long int a, unsigned long long int b) {
unsigned long long int c = 1; /* jebeš math.h ke nima funkcije za intager */
for (; b > 0; b--) { /* potenciranje */
c = c * a;
}
return c;
}
size_t angnum (unsigned long long int n, char * s, int l) {
unsigned int i = 0; // Index Iteracij
int z = 0; // Zapisanih
if (n <= 20) { // "thirteen", namesto 0 je prazen string
z = snprintf(s, l, "%s", j_enice[n]);
fprintf(stderr, "z = %d, l = %d, s = %s, n = %llu\n", z, l, s, n);
return z;
}
if (n <= 99) { // && n > 20 // "forty-one" ali "thirty"
z = snprintf(s, l, "%s", j_desetice[n / 10]); // intdiv je floor
if (z < l && n % 10 != 0) s[z++] = '-';
return z + (n % 10 != 0 ? snprintf(s+z, l-z, "%s", j_enice[n % 10]) : 0);
}
if (n <= 999) { // && n > 99
z = snprintf(s, l, "%s ", j_enice[n/100]); // "one "
z = z + snprintf(s+z, l-z, "%s", J_1h); // "hundred"
if (n % 100 != 0) {
if (z < l) s[z++] = ' ';
z = z + snprintf(s+z, l-z, "%s ", J_AND); // "and "
return z + angnum(n-(n/100)*100, s+z, l-z);
} else {
return z;
}
} // sedaj je n > 99 && n < 1e21
for (i = 3; i <= 21; i=i+3) // sedaj iščemo največjo tisočico
if (n / na(10, i) <= 999) // zadnja tisočica
break;
z = angnum((n/na(10, i)), s, l-z); // "three hundred and forty-two"
fprintf(stderr, "-z = %d, l = %d, s = %s, n = %llu\n", z, l, s, n);
z = z + snprintf(s+z, l-z, " %s", j_power[i/3]); // "million"
fprintf(stderr, "xz = %d, l = %d, s = %s, n = %llu\n", z, l, s, n);
if (n-(n/na(i, 10)) > 0) {
fprintf(stderr, "pz = %d, l = %d, s = %s, n = %llu\n", z, l, s, n);
if (z < l) s[z++] = ' ';
if (z < l) s[z++] = 'a';
if (z < l) s[z++] = 'n';
if (z < l) s[z++] = 'd';
if (z < l) s[z++] = ' ';
fprintf(stderr, "qz = %d, l = %d, s = %s, n = %llu\n", z, l, s, n);
z = z + angnum(n-(n/na(10, i)*na(10, i)), s+z, l-z);
fprintf(stderr, "zz = %d, l = %d, s = %s, n = %llu\n", z, l, s, n);
}
return z;
}
int main (int argc, char ** argv) {
if (argc != 1+1) {
fprintf(stderr, "uporaba: %s <stevilka>\nprimer, ki napiše \"four hundred and twenty\": %s 420\n", argv[0], argv[0]);
return 1;
}
unsigned long long int n = strtoll(argv[1], NULL, 10);
char * s = malloc(sizeof(char)*MX_NS_L);
s[angnum(n, s, MX_NS_L-1)] = '\0';
fprintf(stdout, "%s\n", s);
return 0;
}
|