20.08
2020
Todo mundo sabe que printf faz escrita de dados, e que scanf faz leitura de dados, mas nem todo mundo sabe usar scanf para fazer parser de entrada de dados. Nest post vamos ensinar a fazer parser de formatos básicos usando scanf.
Primeiro a sintaxe básica:
scanf(<FORMATO>, <VAR1>, <VAR2>,...);
O formato é uma string, podendo ser um literal, que contém o formato a ser lido, e uma série de especificadores de formato. Cada especificador de formato irá gerar um conteúdo para sua respectiva variável (VAR1, VAR2…). E a quantidade de variáveis depende da quantidade de especificadores de formato.
O valor do retorno é a quantidade de variáveis aonde foi feito o parser corretamente.
Vamos agora a lista de especificadores de formato:
- %c – um único caracter
- %d – número inteiro na base 10
- %i – número inteiro na base 10, 8 ou 16
- %e, %f ou %g – número de ponto flutuante
- %o – número na base 8
- %s – string
- %x – número hexadecimal
- %p – ponteiro
- %n – um inteiro igual ao número de caracteres lidos até o momento
- %u – um número natural na base 10
- %[] – um conjunto de caracteres
- %% – um caracter %
Vamos começar bem básico, lendo 3 caracteres:
char c1, c2, c3;
scanf("%c%c%c", &c1, &c2, &c3);
O código acima vai aceitar caracteres digitados até que o usuário digite ENTER. Porém somente fará a leitura dos três primeiros caracteres. E o retorno será 3.
Para ler uma data no formato YYYY-MM-DD, basta usar o código abaixo:
unsigned year, month, mday;
scanf("%04d-%02d-%02d", &year, &month, &mday);
Para saber se o parser ocorreu com sucesso, basta conferir o valor retornado. No caso acima em caso de sucesso o valor deve ser três.
É possível, inclusive interpretar um arquivo .csv sem utilizar strtok:
scanf("%4d;%2d;%2d;%[^;];%[^;]", &year, &month, &mday, name, email);
Que irá recuperar dados numéricos e textuais dos cinco primeiros campos da linha .csv
Tudo o que foi expresso sobre scanf nesse post também vale para sscanf, para fazer parser de um buffer em memória, e para fscanf, para fazer parser a partir do conteúdo de um arquivo.