Ir para o conteúdo

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