Entrada e saída de dados
printf
“Mas e se eu quiser imprimir uma variável?” ... é só usar a formatação de texto do printf
... “Mas como se usa isso?” ... para imprimir uma variável int
é só escrever um %i
ou %d
dentro da string. Se for um char
, escreva %c
na string, se for float
, escreva %f
, se for uma notação científica (geralmente usada no tipo double
), escreva %E
( se estiver usando o “e” maiúsculo) e %e
para o “e” minúsculo, após escrever a formatação desejada, é só listar as variáveis separando por vírgula ligo após a string... “Eu não entendi nada do que tu disse!” ...Relaxa... Olhe o exemplo e suas dúvidas em relação a isso irão desaparecer:
int numero = 90;
char caractere = 'A';
float real = 9.23;
double real_em_dobro_E = 9.4E13;
double real_em_dobro_e = 9.4e13;
printf("numero inteiro: %i", numero);
printf("numero real: %f", real);
printf("numero real notação cientifica com \"E\": %E", real_em_dobro_E);
printf("numero real notação cientifica com \"e\": %e", real_em_dobro_e);
printf("caractere: %c", caractere);
saída:
numero inteiro: 90
numero real: 9.23
numero real notação cientifica com "E": 9.4E13
numero real notação cientifica com "e": 9.4e13
caractere: A
scanf
O scanf é semelhante ao printf, mas serve para ler dados:
int numero;
scanf("%i", &numero);
Tá, eu sei que você está se perguntando “e esse &
serve pra que?” Esse &
diz para o scanf
colocar o valor no lugar da memória onde está o número. O &
simboliza um endereçamento de memória, o scanf
coloca o valor direto no local da memória onde está a variável.
E como você pode perceber o %i
se refere a um número inteiro. Todos os tipos de variáveis são simbolizados pelos símbolos (%i
, %c
, %f
...) do printf
.
Também é possível ler várias variáveis com um único comando:
int numero;
char caractere;
float real;
printf("digite um numero um caractere e um numero real: \n");
scanf("%i %c %f", &numero, &caractere, &real);
printf("\nnumero inteiro: %i", numero);
printf("numero real: %f", real);
printf("caractere: %c", caractere);
Na hora de ler um
char
, às vezes oscanf
buga, isso ocorre quando ele recebe lixo do teclado, você só precisa ler a variável duas vezes, isso geralmente ocorre comchar
, mas se acontecer com outro tipo, a resolução para o problema é a mesma:
fflush(stdin); // esse comando vai limpar o lixo da memória
Saída:
digite um numero, um caractere e um numero real:
3458
J
5.8769
>
numero inteiro: 3458
numero real: 5.8769
caractere: J
Esses não são os únicos métodos de entrada e saída de dados, mas veremos outros em outros capítulos, esses são o bastante para prosseguirmos nossos estudos.
Formatos do printf e scanf
%s
Strings ou texto, exemplo:
printf("string: '%s'\n", "string");
%d e %i
Inteiros, exemplo:
printf("int: %i\n", 90);
%f
Reais, exemplo:
printf("float: %f\n", 9.3);
E como são números com .
você pode formatar a saída deles, o 9.3
vai ser exibido como 9.300000
, mas eu quero que saia 9.3
printf("float: %.1f\n", 9.3);
Notem que entre o
%
e of
existe um.1
, isso quer dizer que só é para exibir1
numero após a “vírgula”(que no C é um.
).
O protótipo é mais ou menos assim:
printf("%.<decimais>f\n", <numero>);
%c
Caracteres, exemplo:
printf("char: %c\n", 'A');
%o
Numeros octais, exemplo:
printf("int: %o\n", 018);
Numeros octais iniciam com
0
, logo012
é o mesmo que10
%u
Numeros sem sinal, exemplo:
printf("int: %u\n", 18);
%x
Numeros hexadecimais, exemplo:
printf("int: %x\n", 0xDB7B5);
Todo hexadecimal começa com
0x
.
%l
Numeros longos (sempre acompanhado pelo tipo alongado), exemplo:
// Reais longos
printf("double: %lf\n", (double) 9.3);
// Inteiros longos
printf("long int: %li\n", 698);
Putchar e puts
Basicamente o “put” significa coloque, logo, putchar
é coloque um char
:
char c = '\n';
putchar ('j');
putchar ('o');
putchar ('ã');
putchar ('o');
putchar ( c );
putchar ('!');
putchar ( c );
Saída:
joao
!
E seguindo a mesma lógica, puts
é coloque uma string ( o s
é uma abreviação ).
char * str = "string coisada";
puts ( "joao" );
puts ( "!" );
puts ( str );
Saída:
joao
!
string coisada
Uma particularidade do
puts
é que ele adiciona um\n
no fim da string.
Getchar e gets
Assim como o scanf
, o getchar
e o gets
, são funções para leitura de dados, mas que só servem para ler variáveis do tipo char
e strings.
É assim que se usa o getchar
:
char j;
j = getchar();
E o gets
é usado assim:
char str [20];
gets(str);
Mesmo o
gets
sendo uma função contraindicada pela comunidade, ela ainda funciona, então caso o gcc aponte erros pelo uso dogets
, saiba que ela vai funcionar normalmente.
Fprintf e fgets
O f
antes do printf
significa formatação, logo, um fprintf
é um printf
formatado, e essa formatação é basicamente um parâmetro a mais indicando o lugar onde você quer escrever a informação.
fprintf(stdout, "Hello mundo!!\n"); // printf ( "Hello mundo!!" )
O
stdout
é um “stream” ( local para onde vai a string dofprintf
), e oprintf
é umfprintf
com ostdout
como “stream”, e ostdout
é a saída padrão (a tela).
Mas também é possível enviar a saída para outros streams, dentre eles nós temos o stderr
, que é a saída padrão de erros:
char coisa [30];
puts("escreva de 1 a 10 caracteres: ");
scanf ("%s", &coisa );
if (coisa [0] == '\0' ) {
fprintf ( stderr, "ERROR: você não digitou nenhum caractere!");
return 1;
}
if (coisa [10] != '\0' ) {
fprintf ( stderr, "ERROR: você digitou caracteres demais!");
return 1;
}
No programa acima são pedidos caracteres de 1 a 10, então se o caractere da posição
0
corresponder ao fim de uma string ('\0'
) quer dizer que 0 caracteres foram lidos, e se o 11º caractere (posição10
) for o fim da string ('\0'
) quer dizer que existem mais de 10 caracteres na string.
Note que quando ocorreu um erro o valor retornado foi o 1
, indicando para o sistema operacional que aconteceu um erro.
O fgets
seria um gets
formatado, e ele funciona da seguinte maneira:
char str[10];
fgets ( stdin, 10, str ); // gets (str)
O
stdin
é a entrada de dados padrão (o teclado).
“Ué? Então por que eu deveria usar esse fgets
aí se o gets
é mais simples?” ...Muito simples, lembra que o gets
tem um problema, tanto que ele é contra-indicado pelo próprio compilador? Pois é, o fgets
não tem esse problema, porque nele além de você indicar a string a ser lida e o “stream”, ele exige que você coloque o tamanho da string, assim evitando colocar dados no lugar errado.