continuação da aula 9

This commit is contained in:
Blau Araujo 2025-04-02 14:06:16 -03:00
parent ed4f3e4f6a
commit 48b4393585
2 changed files with 146 additions and 0 deletions

View file

@ -161,3 +161,99 @@ int main(int argc, char **argv) {
return 0;
}
#+end_src
** Conversão de strings para números
Como todos os argumentos são recebidos como strings, haverá situações em
que eles deverão ser convertidos para os valores numéricos correspondentes.
*** Exemplo: programa =soma.c=
#+begin_src c
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
long str2int(char *str) {
int num; // Recebe o inteiro convertido.
char *end; // Recebe o endereço onde termina o inteiro na string.
errno = 0; // Zerar a variável global 'errno'.
// Converte a parte numérica inicial de 'str' pata long int.
num = strtol(str, &end, 10);
// Checagem de erros...
if (str == end) {
// A parte inicial da string não era numérica...
fprintf(stderr, "Nenhum dígito encontrado!\n");
exit(EXIT_FAILURE);
} else if (errno == ERANGE) {
// O número está fora dos limites do tipo 'long int'...
fprintf(stderr, "Número fora dos limites!\n");
exit(EXIT_FAILURE);
} else if (*end != '\0') {
// Caracteres não convertidos restantes...
fprintf(stderr, "Caracteres inválidos: %s\n", end);
exit(EXIT_FAILURE);
}
return num;
}
int main(int argc, char **argv) {
int soma = 0;
int num;
for (int i = 1; i < argc; i++) {
num = str2int(argv[i]);
if (i == 1) {
printf("%d ", num);
} else {
printf("+ %d ", num);
}
soma += num;
}
printf("= %d\n", soma);
return 0;
}
#+end_src
Aqui, nós usamos a função =strtol=, que converte os dígitos encontrado na parte
inicial de uma string em seu correspondente numérico com o tipo =long int= na
base numérica especificada no terceiro argumento.
#+begin_src c
long strtol(const char *restrict nptr, char **_Nullable restrict endptr, int base);
#+end_src
Seu retorno é o valor numérico convertido, a menos que o valor exceda os limites
do tipo =long int=, o que fará com que o retorno seja =LONG_MIN= ou =LONG_MAX=. Se esta
for a situação, a global =errno= receberá o valor da constante simbólica =ERANGE=,
o que nos levou a utilizar o cabeçalho =errno.h= no exemplo.
#+begin_quote
Como a conversão pode retornar o valor =0=, é preciso inicializar =errno= com =0= antes
de chamar =strtol=.
#+end_quote
Ao fazer a conversão, o endereço do término da parte numérica é registrado no
parâmetro =endptr=, o que possibilita fazer diversas verificações, como:
- Se o endereço em =endptr= for igual ao endereço do início da string, a parte
inicial contém dígitos;
- Se o valor em =endptr= for igual a =\0=, a string só contém dígitos.
Além disso, se houver uma parte final não numérica, ela pode ser recuperada
a partir do endereço em =endptr=.
*Compilando e executando...*
#+begin_example
:~$ gcc -Wall -o soma soma.c
:~$ ./soma 1 2 3 4
1 + 2 + 3 + 4 = 10
#+end_example

50
aulas/09-args/soma.c Normal file
View file

@ -0,0 +1,50 @@
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
long str2int(char *str) {
int num; // Recebe o inteiro convertido.
char *end; // Recebe o endereço onde termina o inteiro na string.
errno = 0; // Zerar a variável global 'errno'.
// Converte a parte numérica inicial de 'str' pata long int.
num = strtol(str, &end, 10);
// Checagem de erros...
if (str == end) {
// A parte inicial da string não era numérica...
fprintf(stderr, "Nenhum dígito encontrado!\n");
exit(EXIT_FAILURE);
} else if (errno == ERANGE) {
// O número está fora dos limites do tipo 'long int'...
fprintf(stderr, "Número fora dos limites!\n");
exit(EXIT_FAILURE);
} else if (*end != '\0') {
// Caracteres não convertidos restantes...
fprintf(stderr, "Caracteres inválidos: %s\n", end);
exit(EXIT_FAILURE);
}
return num;
}
int main(int argc, char **argv) {
int soma = 0;
int num;
for (int i = 1; i < argc; i++) {
num = str2int(argv[i]);
if (i == 1) {
printf("%d ", num);
} else {
printf("+ %d ", num);
}
soma += num;
}
printf("= %d\n", soma);
return 0;
}