/
ch-2.cpp
81 lines (74 loc) · 1.75 KB
/
ch-2.cpp
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
/*
Challenge 002
Challenge #2
Write a script that can convert integers to and from a base35
representation, using the characters 0-9 and A-Y. Dave Jacoby came up
with nice description about base35, in case you needed some background.
*/
#include <iostream>
#include <string>
#include <cctype>
// format a digit
char format_digit(int n) {
if (n < 10)
return '0' + n;
else
return 'A' + n - 10;
}
// format a number
std::string format_number(int n, int base) {
bool negative = false;
std::string str;
if (n < 0) {
negative = true;
n = -n;
}
do {
int d = n % base;
n = n / base;
str.insert(0, 1, format_digit(d));
} while (n > 0);
if (negative)
str.insert(0, 1, '-');
return str;
}
// scan digit
int scan_digit(char c) {
if (isdigit(c))
return c - '0';
else if (isalpha(c))
return toupper(c) - 'A' + 10;
else
return -1;
}
// scan number
int scan_number(const std::string& str, int base) {
const char* p = str.c_str();
bool negative = false;
int n = 0;
if (*p == '-') {
negative = true;
p++;
}
while (*p != '\0') {
int d = scan_digit(*p++);
if (d < 0 || d >= base) {
std::cerr << "invalid number" << std::endl;
exit(EXIT_FAILURE);
}
n = n * base + d;
}
if (negative)
n = -n;
return n;
}
int main(int argc, char* argv[]) {
if (argc == 2)
std::cout << format_number(atoi(argv[1]), 35) << std::endl;
else if (argc == 3 && std::string(argv[1]) == "-r")
std::cout << scan_number(argv[2], 35) << std::endl;
else {
std::cerr << "Usage: ch-2 [-r] number" << std::endl;
return EXIT_FAILURE;
}
}