/*
 * Arquivo   : uint.c
 * Compilação: gcc -Wall uint.c -o uintc
 */
#include <stdio.h>
#include <limits.h> // Requerido para obter UINT_MAX da plataforma

unsigned int str_to_uint(char *str, int *err /* nullable */);

int main(int argc, char **argv) {
    if (argc == 1) {
        fprintf(stderr, "Uso: %s NÚMERO\n", argv[0]);
        return 1;
    }

    int status;
    unsigned int num = str_to_uint(argv[1], &status);

    if (status) {
        printf("String: %s\nNúmero: %u\n", argv[1], num);
    } else {
        fprintf(stderr, "Erro de conversão!\n");
        return 1;
    }

    return 0;
}

unsigned int str_to_uint(char *str, int *err /* nullable */) {
    if (err) *err = 0;  // Estado padrão é de erro (0 = falso)!
    
    // Termina com erro e valor 0 se str==NULL ou se '0'>str[0]>'9'...
    if (str == NULL || str[0] < '0' || str[0] > '9') return 0;
   
    int dig;               // Recebe o dígito convertido
    unsigned int conv = 0; // Recebe a parcial da conversão
    
    for (int i = 0; str[i] != '\0'; i++) {
        // Se o caractere não for um dígito, termina a conversão...
        if (str[i] < '0' || str[i] > '9') break;
        // Converte o dígito corrente...
        dig = str[i] - '0';
        // Termina com erro e valor 0 se a próxima conversão exceder UINT_MAX...
        if (conv > (UINT_MAX - dig) / 10) return 0;
        // Processa a parcial da conversão...
        conv = (conv * 10) + dig;
    }
    
    if (err) *err = 1;  // Altera estado para sucesso (1 = verdadeiro)
    return conv;
}
