Escolar Documentos
Profissional Documentos
Cultura Documentos
Aula 7
Entrada e Saída
Departamento de Computação
Universidade Federal de Ouro Preto
2011.2
1/86
. . . . . .
1 Interação com o mundo
3 Programa em Haskell
6 Saída bufferizada
7 Expressão do
8 readLn e print
9 Números aleatórios
10 Arquivos
2/86
. . . . . .
Layout
3 Programa em Haskell
6 Saída bufferizada
7 Expressão do
8 readLn e print
9 Números aleatórios
10 Arquivos
3/86
. . . . . .
Programas interativos
4/86
. . . . . .
Exemplo de programa interativo em C
int main(void)
{
char x = getchar();
char y = getchar();
printf(”%c%c\n”, toupper(x), toupper(y));
return 0;
}
Supondo que o usuário informe os caracteres ’A’ e ’b’, a execução do
programa produzirá a seguinte interação:
Ab
AB
5/86
. . . . . .
Exemplo de programa interativo em C (cont.)
6/86
. . . . . .
Linguagens puras
7/86
. . . . . .
O mundo
8/86
. . . . . .
Modificando o mundo
9/86
. . . . . .
A função primitiva getChar
10/86
. . . . . .
A função primitiva putChar
11/86
. . . . . .
Exemplo usando getChar e putChar
prog world =
let (c1,world1) = getChar world
(c2,world2) = getChar world1
world3 = putChar (toUpper c1) world2
world4 = putChar (toUpper c2) world3
in world4
prog é uma função que:
1 recebe um mundo como argumento,
2 obtém dois caracteres da entrada padrão (um componente do mundo),
3 exibe-os em maiúsculas na saída padrão (outro componente do mundo), e
4 retorna um novo mundo igual ao primeiro exceto pelos dispositivos de
entrada e saída: dois caracteres foram extraídos da entrada e dois
caracteres foram inseridos na saída.
12/86
. . . . . .
Execução seqüencial
13/86
. . . . . .
Exemplo: lendo uma linha
14/86
. . . . . .
Exemplo: escrevendo uma string
15/86
. . . . . .
Exemplo: escrevendo uma string (cont.)
16/86
. . . . . .
Exemplo: soma de dois números
main world =
let world1 = putStr ”Digite um número: ” world
(str1,world2) = getLine world1
world3 = putStr ”Digite outro número: ” world2
(str2,world4) = getLine world3
world5 = putStrLn (show (read str1 + read str2)) world4
in world5
17/86
. . . . . .
Layout
3 Programa em Haskell
6 Saída bufferizada
7 Expressão do
8 readLn e print
9 Números aleatórios
10 Arquivos
18/86
. . . . . .
O construtor de tipo IO
19/86
. . . . . .
O construtor de tipo IO (cont.)
ou seja, uma operação de entrada e saída poderia ser uma função que
recebe um mundo como argumento e interage com este mundo produzindo
um valor e um novo mundo como resultados.
20/86
. . . . . .
A operação getChar
getChar :: IO Char
21/86
. . . . . .
A função putChar
22/86
. . . . . .
Layout
3 Programa em Haskell
6 Saída bufferizada
7 Expressão do
8 readLn e print
9 Números aleatórios
10 Arquivos
23/86
. . . . . .
Programa em Haskell
24/86
. . . . . .
Exemplo de programa em Haskell
main :: IO ()
main = putChar ’A’
25/86
. . . . . .
Preparando e executando um programa em Haskell
26/86
. . . . . .
Layout
3 Programa em Haskell
6 Saída bufferizada
7 Expressão do
8 readLn e print
9 Números aleatórios
10 Arquivos
27/86
. . . . . .
Sequenciamento de operações
28/86
. . . . . .
Sequenciamento simples
infixl 1 >>
(>>) :: IO a -> IO b -> IO b
29/86
. . . . . .
Sequenciamento simples (cont.)
▶ Exemplo:
Exibir dois caracteres na tela:
main = putChar ’A’ >> putChar ’B’
30/86
. . . . . .
Sequenciamento simples (cont.)
▶ Exemplo:
Ler um caracter e ignorá-lo, e exibir três outros caracteres:
main = getChar >>
putChar ’F’ >>
putChar ’i’ >>
putChar ’m’
31/86
. . . . . .
Sequenciamento simples (cont.)
32/86
. . . . . .
Sequenciamento com passagem de resultado
infixl 1 >>=
(>>=) :: IO a -> (a -> IO b) -> IO b
▶ Recebe uma ação e uma função (que resulta em outra ação) como
argumentos.
▶ Executa a primeira ação.
▶ Em seguida aplica a função ao resultado da primeira ação, o que faz com
que a segunda ação seja executada.
▶ Desta forma o resultado da primeira ação é passado como argumento para
a função dada.
33/86
. . . . . .
Sequenciamento com passagem de resultado (cont.)
▶ Exemplo:
Ler um caracter e exibi-lo na tela:
main = getChar >>= (\x -> putChar x)
ou ainda
main = getChar >>= \x -> putChar x
ou ainda
main = getChar >>= \x ->
putChar x
ou ainda
main = getChar >>= putChar
34/86
. . . . . .
Sequenciamento com passagem de resultado (cont.)
▶ Exemplo:
Ler um caracter e exibi-lo em maiúsculas na tela:
main = getChar >>= (\x -> putChar (toUpper x))
ou ainda
main = getChar >>= (putChar . toUpper)
35/86
. . . . . .
Sequenciamento com passagem de resultado (cont.)
▶ Exemplo:
Ler um caracter e exibi-lo em minúsculas e em maiúsculas na tela:
getChar >>= (\x -> putChar (toLower x) >> putChar (toUpper x))
ou ainda
getChar >>= \x -> putChar (toLower x) >> putChar (toUpper x)
ou ainda
getChar >>= \x ->
putChar (toLower x) >>
putChar (toUpper x)
36/86
. . . . . .
Sequenciamento com passagem de resultado (cont.)
37/86
. . . . . .
Sequenciamento com passagem de resultado (cont.)
38/86
. . . . . .
Função return
return :: a -> IO a
39/86
. . . . . .
Função return (cont.)
40/86
. . . . . .
Layout
3 Programa em Haskell
6 Saída bufferizada
7 Expressão do
8 readLn e print
9 Números aleatórios
10 Arquivos
41/86
. . . . . .
A operação getLine
getLine :: IO String
42/86
. . . . . .
A função putStr
43/86
. . . . . .
A função putStrLn
44/86
. . . . . .
Exemplo: soma de dois números
soma.hs
module Main (main) where
main :: IO ()
main = putStr ”Digite um número: ” >>
getLine >>= \s1 ->
putStr ”Digite outro número: ” >>
getLine >>= \s2 ->
putStr ”Soma: ” >>
putStrLn (show (read s1 + read s2))
Execução do programa onde o usuário informa os números 34 e 17:
34
17
Digite um número: Digite outro número: Soma: 51
O que aconteceu de errado?
45/86
. . . . . .
Layout
3 Programa em Haskell
6 Saída bufferizada
7 Expressão do
8 readLn e print
9 Números aleatórios
10 Arquivos
46/86
. . . . . .
Saída bufferizada
47/86
. . . . . .
Saída bufferizada (cont.)
48/86
. . . . . .
Saída bufferizada (cont.)
▶ A expressão
hSetBuffering hdl mode
no começo da sequência.
49/86
. . . . . .
Saída bufferizada (cont.)
soma2.hs
module Main (main) where
main :: IO ()
main = hSetBuffering stdout NoBuffering >>
putStr ”Digite um número: ” >>
getLine >>= \s1 ->
putStr ”Digite outro número: ” >>
getLine >>= \s2 ->
putStr ”Soma: ” >>
putStrLn (show (read s1 + read s2))
Execução do programa onde o usuário informa os números 34 e 17:
$ ./soma2
Digite um número: 34
Digite outro número: 17
Soma: 51
50/86
. . . . . .
Saída bufferizada (cont.)
Exercício 1
Escreva um programa em Haskell que solicita ao usuário uma temperatura na
escala Fahrenheit, lê esta temperatura, converte-a para a escala Celsius, e exibe
o resultado. Use os operadores (>>) e (>>=).
Use a seguinte equação para a conversão:
5
C= × (F − 32)
9
51/86
. . . . . .
Layout
3 Programa em Haskell
6 Saída bufferizada
7 Expressão do
8 readLn e print
9 Números aleatórios
10 Arquivos
52/86
. . . . . .
Expressão do
53/86
. . . . . .
Expressão do (cont.)
▶ Exemplo:
Um programa para ler dois números e exibir a sua soma:
module Main (main) where
main :: IO ()
main = do { hSetBuffering stdout NoBuffering;
putStr ”Digite um número: ”;
s1 <- getLine;
putStr ”Digite outro número: ”;
s2 <- getLine;
putStr ”Soma: ”;
putStrLn (show (read s1 + read s2))
}
54/86
. . . . . .
Expressão do (cont.)
55/86
. . . . . .
Expressão do (cont.)
▶ Exemplo:
Um programa para ler dois números e exibir a sua soma:
module Main (main) where
main :: IO ()
main = do hSetBuffering stdout NoBuffering
putStr ”Digite um número: ”
s1 <- getLine
putStr ”Digite outro número: ”
s2 <- getLine
putStr ”Soma: ”
putStrLn (show (read s1 + read s2))
56/86
. . . . . .
Expressão do (cont.)
do { x ; ações }
≡
x >> do { ações }
do { x }
≡
x
57/86
. . . . . .
Expressão do (cont.)
▶ Exemplo:
do putStrLn ”um”
putStrLn ”dois”
≡
putStrLn ”um” >>
putStrLn ”dois”
58/86
. . . . . .
Expressão do (cont.)
▶ Exemplo:
do x <- getLine
putStrLn (”Você digitou: ” ++ x)
≡
getLine >>= \x ->
putStrLn (”Você digitou: ” ++ x)
59/86
. . . . . .
Expressão do (cont.)
▶ Exemplo:
do let f xs = xs ++ xs
putStrLn (f ”abc”)
≡
let f xs = xs ++ xs
in putStrLn (f ”abc”)
60/86
. . . . . .
Layout
3 Programa em Haskell
6 Saída bufferizada
7 Expressão do
8 readLn e print
9 Números aleatórios
10 Arquivos
61/86
. . . . . .
A ação readLn
62/86
. . . . . .
A função print
63/86
. . . . . .
Exemplo: peso ideal
Programa que recebe a altura e o sexo de uma pessoa e calcula e mostra o seu
peso ideal, utilizando as fórmulas
onde h é a altura.
64/86
. . . . . .
Exemplo: peso ideal (cont.)
pesoideal.hs
module Main (main) where
main :: IO ()
main = do hSetBuffering stdout NoBuffering
h <- leDado ”Altura: ”
s <- leDado ”Sexo (F/M): ”
putStr ”Peso ideal: ”
let pesoIdeal = case s of
F -> 62.1 * h - 44.7
M -> 72.7 * h - 58
print pesoIdeal
65/86
. . . . . .
Exemplo: média de 3 notas
Faça um programa que receba três notas de um aluno, calcule e mostre a média
aritmética das notas e a situação do aluno, dada pela tabela a seguir.
66/86
. . . . . .
Exemplo: média de 3 notas (cont.)
media3notas.hs
module Main (main) where
main :: IO ()
main = do hSetBuffering stdout NoBuffering
n1 <- leDado ”Nota 1: ”
n2 <- leDado ”Nota 2: ”
n3 <- leDado ”Nota 3: ”
let media = (n1 + n2 + n3)/3
putStrLn (”Média: ” ++ show media)
if media < 3
then putStrLn ”Reprovado”
else if media < 7
then putStrLn ”Exame especial”
else putStrLn ”Aprovado”
67/86
. . . . . .
Exemplo: raízes da equação do segundo grau
68/86
. . . . . .
Exemplo: raízes da equação do segundo grau (cont.)
raizes2grau.hs
module Main (main) where
raizes2grau a b c
| d > 0 = [ (-b + sqrt d)/(2*a), (-b - sqrt d)/(2*a) ]
| d = 0 = [ -b/(2*a) ]
| otherwise = [ ]
where d = b^2 - 4*a*c
calcRaizes2grau =
do putStrLn ”Cálculo das raízes da equação do segundo grau”
putStrLn ”a x^2 + b x + c = 0”
a <- prompt ”Coeficiente a: ”
b <- prompt ”Coeficiente b: ”
c <- prompt ”Coeficiente c: ”
case raizes2grau a b c of
[r1,r2] -> 69/86
. . . . . .
Exemplo: raízes da equação do segundo grau (cont.)
70/86
. . . . . .
Layout
3 Programa em Haskell
6 Saída bufferizada
7 Expressão do
8 readLn e print
9 Números aleatórios
10 Arquivos
71/86
. . . . . .
Números aleatórios
Esta função recebe um par de valores (inf , sup) e retorna uma operação de
entrada e saída que obtém o próximo valor aleatório do tipo a
uniformemente distribuído no intervalo [inf , sup].
72/86
. . . . . .
Números aleatórios (cont.)
main :: IO ()
main =
do putStrLn ”Lançamento de dois dados”
x <- randomRIO (1,6::Int)
y <- randomRIO (1,6::Int)
putStrLn (”Faces obtidas: ” ++ show x ++ ” e ” ++ show y)
73/86
. . . . . .
Números aleatórios (cont.)
Execução do programa:
$ ./lancadados
Lancamento de dois dados
Faces obtidas: 3 e 5
$ ./lancadados
Lancamento de dois dados
Faces obtidas: 4 e 1
74/86
. . . . . .
Exemplo: adivinhe o número
75/86
. . . . . .
Exemplo: adivinhe o número (cont.)
adivinha.hs
module Main (main) where
main :: IO ()
main =
do hSetBuffering stdout NoBuffering
putStrLn ”Adivinhe o número v1.0”
putStrLn ”==========================================”
jogar
jogar :: IO ()
jogar =
do numero <- randomRIO (1,1000)
acertar numero
putStrLn ””
deseja <- simOuNao ”Deseja jogar novamente? (s/n) ”
if deseja
then jogar 76/86
. . . . . .
Exemplo: adivinhe o número (cont.)
else return ()
78/86
. . . . . .
Layout
3 Programa em Haskell
6 Saída bufferizada
7 Expressão do
8 readLn e print
9 Números aleatórios
10 Arquivos
79/86
. . . . . .
Arquivos
▶
type FilePath = String
▶
readFile :: FilePath -> IO String
▶
writeFile :: FilePath -> String -> IO ()
▶
appendFile :: FilePath -> String -> IO ()
80/86
. . . . . .
Exemplo: processar notas em arquivo
Criar um programa para ler de um arquivo os dados dos alunos de uma turma – o
código, o nome, a nota na primeira avaliação, a nota na segunda avaliação –
calcular a média aritmética das notas e determinar a situação de cada aluno,
gravando os resultados em outro arquivo.
81/86
. . . . . .
Exemplo: processar notas em arquivo (cont.)
Arquivo de entrada:
1234 Pedro 1.5 1.7
1111 Carla 6.2 7.0
2121 Rafael 8.1 8.8
4321 Ivan 5.0 5.2
82/86
. . . . . .
Exemplo: processar notas em arquivo (cont.)
leNotas arquivo =
do s <- readFile arquivo
return (map (f . words) (lines s))
where
f [cod,nom,n1,n2] = (cod,nom,read n1,read n2)
processaNotas notas =
map f notas
where
f (cod,nom,n1,n2) = (cod,nom,n1,n2,med,sit)
where
med = (n1 + n2)/2
sit | med < 3 = ”reprovado”
| med < 7 = ”exame especial”
| otherwise = ”aprovado”
main =
do hSetBuffering stdout NoBuffering
arq1 <- putStr ”Arquivo de entrada: ” >> getLine
arq2 <- putStr ”Arquivo de saída: ” >> getLine
notas <- leNotas arq1
let res = processaNotas notas
escreveResultado arq2 res
84/86
. . . . . .
Exemplo: processar notas em arquivo (cont.)
Arquivo de saída:
1234 Pedro 1.5 1.7 1.6 reprovado
1111 Carla 6.2 7.0 6.6 exame especial
2121 Rafael 8.1 8.8 8.45 aprovado
4321 Ivan 5.0 5.2 5.1 exame especial
85/86
. . . . . .
Fim
86/86
. . . . . .