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!

7 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