sexta-feira, 22 de fevereiro de 2008

lendo dados - a função scanf

Agora que você sabe como funciona o operador de endereço &, posso apresentar a você a função scanf (leia-se scanEFE).
Essa função, como a printf, está localizada na biblioteca stdio.h e serve como entrada de dados em seu programa. Tudo aquilo que você digita no teclado será lido por essa função.
É claro que para o scanf você deverá informar duas coisas:
  1. Em qual formato o dado será lido?
  2. Onde ele será armazenado?

Para informar o formato do dado para o scanf é necessário recorrer a tabela abaixo:
CódigoFormatação
%cLê um caractere
%dLê um inteiro positivo ou negativo (base decimal)
%iLê um inteiro positivo ou negativo (base decimal)
%eLê um número de ponto flutuante em notação científica
%fLê um número de ponto flutuante
%gLê um número de ponto flutuante podendo ser expressa em notação científica
%oLê um número em octal
%sLê uma cadeia de caracteres (string)
%uLê um inteiro sem sinal
%xLê um número hexadecimal
%nRecebe um valor inteiro correspondente ao número de caracteres lidos até então
%[]Busca por um conjunto de caracteres

A resposta genérica para a segunda pergunta é a memória. Devemos especificar para o scanf qual o endereço de memória ele deve guardar o dado inserido. Para essa operação utiliza-se o operador de endereço &.
A forma geral do scanf é:


scanf("código de formatação", lista de endereços);


Para ler duas variáveis, sexo e anoNascimento podemos fazer como no programa abaixo.


001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char *argv[])
005:  {
006:    char sexo;
007:    int anoNascimento;
008:    printf("Digite o sexo\n[F] - Feminino\n[M] - Masculino\n");
009:    scanf("%c",&sexo);
010:    printf("Digite o ano de nascimento: ");
011:    scanf("%d",&anoNascimento);
012:    system("PAUSE");
013:    return 0;
014:  }


Note que nas linhas 9 e 11 o código de formatação indica somente o tipo de dado a ser lido.
O scanf permite ler mais de uma variável na mesma instrução. Adaptando o programa acima para ler em apenas uma instrução fica da seguinte forma:


001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char *argv[])
005:  {
006:    char sexo;
007:    int anoNascimento;
008:    printf("Digite o sexo\n[F] - Feminino\n[M] - Masculino\nEm seguida digite o ano de nascimento.");
009:    scanf("%c%d",&sexo, &anoNascimento);
010:    system("PAUSE");
011:    return 0;
012:  }


Particularmente não gosto dessa segunda opção porque não permite a limpeza do buffer do teclado entre uma leitura e outra. A limpeza é importante pois garante que nenhuma sujeira presente no buffer contaminará suas variáveis.
Para fazer a limpeza do buffer basta inserir a instrução


fflush(stdin);


antes de cada scanf.
Veja o primeiro programa escrito de uma forma mais segura.


001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char *argv[])
005:  {
006:    char sexo;
007:    int anoNascimento;
008:    printf("Digite o sexo\n[F] - Feminino\n[M] - Masculino\n");
009:    fflush(stdin);
010:    scanf("%c",&sexo);
011:    printf("Digite o ano de nascimento: ");
012:    fflush(stdin);
013:    scanf("%d",&anoNascimento);
014:    system("PAUSE");
015:    return 0;
016:  }


Agora sim, ler dados ficou ainda mais fácil!

8 comentários:

Anônimo disse...

quanto ao scanf() há uma coisa que ainda não entendi mas que gostaría de ser esclarecido,se souber.
Porquê só é necessário limpar o buffer do teclado quando se usa scanf)com o código de formatação %c ?

Fernando Ferreira disse...

Parabéns por esse post. Objetivo e claro!

Fernando!

Anônimo disse...

Cara vc é melhor que meu prof de algoritmos... vlw me ajudou na hora de limpar o buffer do teclado, já que dava erro quando eu digitava um valor.

VLW

caio disse...

qual é o codigo do SCANF para fazer aparecer um texto no PRINTF?

Luiz Fernando Oliveira Silva disse...

caio.

Quando você receber um valor CHAR.
use "gets(nome_variavel)";

Para exibir esse valor basta usar um printf

PRINTF("Seu texto eh: %s", nome_variavel);

Vinicius Borba disse...

Cara parabens pelo POST, ja fiz aula de linguagem C, mas no momento estou trabalhando com Sockets em um projeto e tive um problema que não ia conseguir resolver nunca, até achar seu post.(Mesmo não tendo NADA a ver com sockets rsrss)

Galera com duvidas sobre o porque limpar o buffer do teclado, tenho um bom motivo aqui...

Tente fazer o seguinte:

bibliotecas <>

#define frase "Testanto retorno do SCANF By Vinicius Borba (BorbaEH)"

int x;
char nada[20];

while(1){
x = scanf("%s",&nada);
printf("Scanf: %s x = %d\n",nada,x);
getch();

}

Viu que interessante??? Era para o scanf pedir a entrada novamente para você, mas não, ele continua escrevendo em blocos de palavras. Ahh... O getch é para controlar o loop infinito. rsrs

Usando o fflush isso não ocorre porque ele limpa.
E eu abri a biblioteca do scanf pensando que era o retorno da função que entrava como argumento no scanf novamente. o.O' hahaaa
Como não sei, mas pelo que entendi o teclado armazena o que não foi 'lido' e joga denovo pro scanf. Que coisa!!! haha

Abraço"

email: viniciusreis6@hotmail.com

xXxChri$topheRxXx disse...

valeu cara, esclareceu bem

Jonathan disse...

A rotina scanf e muito útil mais não podemos deixar de lado os outros métodos de captura de dados como os da biblioteca conio.h

Para quem quiser ver um vídeo sobre scanf eu vou deixar este link que mostra o comando na pratica.

https://goo.gl/cXeUMN