Como usar o scanf para strings com espaços
Um dos mitos que existem sobre o C é que não é possível ler strings que tenham espaços e outros caracteres especiais com o scanf
. Este artigo pretende destruir este mito.
Existem as seguintes sequências de controlo para o scanf
e printf
:
Caracter de controlo | Descrição |
---|---|
%c |
um caracter (exemplo: 'a') |
%i |
um número inteiro |
%d |
um número inteiro em decimal (exemplo: 1) |
%e , %f , %g |
um float (exemplo: 5.9785) |
%o |
um número em octal |
%s |
uma simples string |
%x |
um número em hexadecimal |
%p |
um ponteiro |
%n |
um inteiro equivalente ao número de caracteres escritos até ali naquela iteração |
%u |
um unsigned integer |
%[] |
um conjunto de caracteres |
%% |
o símbolo % |
Como se pode ver, existe uma sequência de controlo mais flexível que o %s
: o %[]
.
Graças a esta sequência de controlo, podemos escolher o que queremos ler. Dentro dos parênteses escrevemos os caracteres permitidos (ex: %[aeiou]
) ou negados (ex: %[^aeiou]
). Para lermos uma string podemos usar, por exemplo, %[^\n]
, que vai ler todos os caracteres até encontrar o \n
neste caso (o \n
não é incluído na string). A sintaxe deste especificador funciona de modo semelhante às expressões regulares POSIX.
Se quisermos limitar o tamanho da string, podemos limitá-la antes do conjunto de caracteres a ler. Neste exemplo, vamos ler uma string com 60 caracteres no máximo: %60[^\n]
.
Notas
Algoritmo de input de dados em C:
/* Ler os dados */
scanf("%[^\n]", str);
/* Limpar o buffer */
scanf("%*[^\n]"); scanf("%*c");
/* Voltar ao passo 1. */
O %n
funciona do seguinte modo:
#include <stdio.h>
int main()
{
int n, tmp;
printf("Hello%n\n", &n);
tmp = n;
printf("Nº de chars escritos até agora: %d\n", tmp);
printf("World!%n\n",&n);
tmp += n;
printf("Nº de chars escritos até agora: %d\n", tmp);
return 0;
}
Resultado:
Hello
Nº de chars escritos até agora: 5
World!
Nº de chars escritos até agora: 11