Função de conversão de strings para inteiros sem sinal #22

Open
opened 2025-06-05 14:10:02 -03:00 by blau_araujo · 0 comments
Owner

Essa é a função que eu uso na aula 9 do curso de programação em baixo nível para demonstrar a conversão de strings para inteiros sem sinal.

#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;
}

Compilação e testes:

:~$ gcc -Wall uint.c -o uintc
$ ./uintc
Uso: ./uintc NÚMERO
:~$ ./uintc 123
String: 123
Número: 123
:~$ ./uintc 123abc
String: 123abc
Número: 123
:~$ ./uintc $((2**32))
Erro de conversão!
:~$ ./uintc $((2**32 - 1))
String: 4294967295
Número: 4294967295
:~$ ./uintc ''
Erro de conversão!
:~$ ./uintc abc
Erro de conversão!

Editado

Eu voltei os tipos para unsigned int porque copiei, sem querer, a versão que converte para unsigned long int (size_t) em que estava trabalhando.

Essa é a função que eu uso na aula 9 do curso de programação em baixo nível para demonstrar a conversão de strings para inteiros sem sinal. ```c #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; } ``` Compilação e testes: ``` :~$ gcc -Wall uint.c -o uintc $ ./uintc Uso: ./uintc NÚMERO :~$ ./uintc 123 String: 123 Número: 123 :~$ ./uintc 123abc String: 123abc Número: 123 :~$ ./uintc $((2**32)) Erro de conversão! :~$ ./uintc $((2**32 - 1)) String: 4294967295 Número: 4294967295 :~$ ./uintc '' Erro de conversão! :~$ ./uintc abc Erro de conversão! ``` ## Editado Eu voltei os tipos para `unsigned int` porque copiei, sem querer, a versão que converte para `unsigned long int` (`size_t`) em que estava trabalhando.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: blau_araujo/cblc#22
No description provided.