Это было действительно интересной задачей для меня, чтобы узнать немного больше о C ++.
Допустим, код довольно большой и содержит множество проверок ошибок, но это только показывает, сколько разных вещей может пойти не так во время синтаксического анализа.
#include <ctype.h>
#include <limits.h>
#include <stdio.h>
#include <iterator>
#include <vector>
#include <string>
static void
die(const char *reason)
{
fprintf(stderr, "aborted (%s)\n", reason);
exit(EXIT_FAILURE);
}
template <class BytePtr>
static bool
read_uint(BytePtr *begin_ref, BytePtr end, unsigned int *out)
{
const unsigned int MAX_DIV = UINT_MAX / 10;
const unsigned int MAX_MOD = UINT_MAX % 10;
BytePtr begin = *begin_ref;
unsigned int n = 0;
while (begin != end && '0' <= *begin && *begin <= '9') {
unsigned digit = *begin - '0';
if (n > MAX_DIV || (n == MAX_DIV && digit > MAX_MOD))
die("unsigned overflow");
n = 10 * n + digit;
begin++;
}
if (begin == *begin_ref)
return false;
*begin_ref = begin;
*out = n;
return true;
}
template <class BytePtr, class IntConsumer>
void
parse_ints(BytePtr begin, BytePtr end, IntConsumer out)
{
while (true) {
while (begin != end && *begin == (unsigned char) *begin && isspace(*begin))
begin++;
if (begin == end)
return;
bool negative = *begin == '-';
if (negative) {
begin++;
if (begin == end)
die("minus at end of input");
}
unsigned int un;
if (!read_uint(&begin, end, &un))
die("no number found");
if (!negative && un > INT_MAX)
die("too large positive");
if (negative && un > -((unsigned int)INT_MIN))
die("too small negative");
int n = negative ? -un : un;
*out++ = n;
}
}
static void
print(int x)
{
printf("%d\n", x);
}
int
main()
{
std::vector<int> result;
std::string input("2147483647 -2147483648 0 00000 1 2 32767 4 -17 6");
parse_ints(input.begin(), input.end(), back_inserter(result));
std::for_each(result.begin(), result.end(), print);
return 0;
}
Я изо всех сил старался не вызывать неопределенного поведения , что может быть довольно сложно при преобразовании чисел без знака в числа со знаком или при вызове isspace
для неизвестного типа данных.