mirror of
https://gitlab.com/blau_araujo/cblc.git
synced 2025-05-14 06:16:36 -03:00
Compare commits
No commits in common. "2fc358accd915d9c1cc35ed61ef71b9182b381a8" and "0cdd9dd6d8a0a8f952a19937d9747c4f1e3ddb75" have entirely different histories.
2fc358accd
...
0cdd9dd6d8
3 changed files with 1 additions and 218 deletions
|
@ -36,7 +36,7 @@ qualquer distribuição.
|
||||||
- [[./aulas/12-fgets][Aula 12: Leitura da entrada padrão com a função 'fgets']] ([[https://youtu.be/ZZr9HBPo0Oc][vídeo]]) ([[./exercicios/12/README.org][exercícios]])
|
- [[./aulas/12-fgets][Aula 12: Leitura da entrada padrão com a função 'fgets']] ([[https://youtu.be/ZZr9HBPo0Oc][vídeo]]) ([[./exercicios/12/README.org][exercícios]])
|
||||||
- [[./aulas/13-read][Aula 13: Leitura da entrada padrão com chamadas de sistema]] ([[https://youtu.be/bW3Xox6LP_U][vídeo]]) ([[./exercicios/13/README.org][exercícios]])
|
- [[./aulas/13-read][Aula 13: Leitura da entrada padrão com chamadas de sistema]] ([[https://youtu.be/bW3Xox6LP_U][vídeo]]) ([[./exercicios/13/README.org][exercícios]])
|
||||||
- [[./aulas/14-rfiles][Aula 14: Abertura de arquivos para leitura]] ([[https://youtu.be/uh3UdYyzXRM][vídeo]]) ([[./exercicios/14/README.org][exercícios]])
|
- [[./aulas/14-rfiles][Aula 14: Abertura de arquivos para leitura]] ([[https://youtu.be/uh3UdYyzXRM][vídeo]]) ([[./exercicios/14/README.org][exercícios]])
|
||||||
- [[./aulas/15-wfiles][Aula 15: Abertura de arquivos para escrita]] ([[https://youtu.be/vL8vy3krcKc][vídeo]]) ([[./exercicios/15/README.org][exercícios]])
|
- [[./aulas/#][Aula 15: Abertura de arquivos para escrita]] ([[https://youtu.be/vL8vy3krcKc][vídeo]]) ([[./exercicios/15/README.org][exercícios]])
|
||||||
- [[./aulas/#][Aula 16: Abertura de arquivos para leitura e escrita]] ([[https://youtu.be/B42KIZfivsg][vídeo]]) ([[./exercicios/16/README.org][exercícios]])
|
- [[./aulas/#][Aula 16: Abertura de arquivos para leitura e escrita]] ([[https://youtu.be/B42KIZfivsg][vídeo]]) ([[./exercicios/16/README.org][exercícios]])
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,124 +0,0 @@
|
||||||
#+title: Curso Básico da Linguagem C
|
|
||||||
#+subtitle: Aula 15: Abertura de arquivos para escrita
|
|
||||||
#+author: Blau Araujo
|
|
||||||
#+startup: show2levels
|
|
||||||
#+options: toc:3
|
|
||||||
|
|
||||||
* Aula 15: Abertura de arquivos para escrita
|
|
||||||
|
|
||||||
[[https://youtu.be/vL8vy3krcKc][Vídeo desta aula]]
|
|
||||||
|
|
||||||
** Modos de abertura de arquivos
|
|
||||||
|
|
||||||
Em relação ao sentido do fluxo de dados, nós podemos realizar duas operações
|
|
||||||
com arquivos abertos: leitura e escrita. Com a função =fopen=, isso é definido
|
|
||||||
em seu segundo argumento através de uma /string de modo/:
|
|
||||||
|
|
||||||
| String | Modo | Descrição |
|
|
||||||
|--------+---------+---------------------------------------------------------------------------------------------------|
|
|
||||||
| ="r"= | Leitura | Abre o arquivo para leitura a partir de seu início. Se o arquivo não existir, causa um erro. |
|
|
||||||
| ="w"= | Escrita | Apaga os dados originais do arquivo para escrever novos. Se o arquivo não existir, ele é criado. |
|
|
||||||
| ="a"= | /Append/ | Abre o arquivo para acrescentar novos dados ao seu final. Se o arquivo não existir, ele é criado. |
|
|
||||||
|
|
||||||
Na chamada de sistema =open=, as strings de modo seriam equivalentes às /flags/:
|
|
||||||
|
|
||||||
- ="r"=: =O_RDONLY=
|
|
||||||
- ="w"=: =O_WRONLY | O_CREAT | O_TRUNC=
|
|
||||||
- ="a"=: =O_WRONLY | O_CREAT | O_APPEND=
|
|
||||||
|
|
||||||
#+begin_quote
|
|
||||||
As /flags/ múltiplas são passadas como operações /OR bit-a-bit/.
|
|
||||||
#+end_quote
|
|
||||||
|
|
||||||
*** Modos complementares
|
|
||||||
|
|
||||||
Incluindo o caractere =+= ao final da string de modo, também será possível
|
|
||||||
realizar a operação oposta:
|
|
||||||
|
|
||||||
| String | Modo | Descrição |
|
|
||||||
|--------+-------------------+-------------------------------------------------------------------------------------------------------------------------------------|
|
|
||||||
| ="r+"= | Leitura e escrita | Posiciona o ponteiro interno no início do arquivo para leitura e escrita. Se o arquivo não existir, causa um erro. |
|
|
||||||
| ="w+"= | Escrita e leitura | Apaga os dados originais do arquivo para escrever novos e ler o que for escrito. Se o arquivo não existir, ele é criado. |
|
|
||||||
| ="a+"= | /Append/ e leitura | Posiciona o ponteiro interno no fim do arquivo para leitura e para acrescentar novos dados. Se o arquivo não existir, ele é criado. |
|
|
||||||
|
|
||||||
#+begin_quote
|
|
||||||
Nós voltaremos a este assunto na próxima aula, mas deve ser evidente que
|
|
||||||
precisaremos controlar o ponteiro interno do arquivo para realizar operações
|
|
||||||
de leitura e escrita em um mesmo /stream/.
|
|
||||||
#+end_quote
|
|
||||||
|
|
||||||
*** Modos texto e binário
|
|
||||||
|
|
||||||
Sistemas /Unix-like/ não fazem distinção entre arquivos texto e binários em
|
|
||||||
operações de entrada e saída (I/O). Portanto, o caractere =b=, que pode ser
|
|
||||||
incluído ao final ou entre os caracteres da string de modo, não terá efeito
|
|
||||||
e só precisaria ser utilizado no caso da possibilidade do programa ser
|
|
||||||
portado para outros sistemas.
|
|
||||||
|
|
||||||
** Modos de escrita
|
|
||||||
|
|
||||||
Em termos gerais, as etapas de trabalho com arquivos abertos para escrita ou
|
|
||||||
/append/ são os mesmos de quando falamos da leitura:
|
|
||||||
|
|
||||||
- Abertura do arquivo para obter um /stream/;
|
|
||||||
- Processamento dos dados;
|
|
||||||
- Fechamento do stream.
|
|
||||||
|
|
||||||
*** Abertura de um arquivo para escrita ("w")
|
|
||||||
|
|
||||||
Neste exemplo, o arquivo =linha.txt= será criado (ou truncado, se já existir)
|
|
||||||
para receber uma linha digitada pelo usuário no terminal:
|
|
||||||
|
|
||||||
#+begin_src c
|
|
||||||
// Abertura do arquivo para escrita...
|
|
||||||
char *file = "linha.txt";
|
|
||||||
FILE *stream = fopen(file, "w");
|
|
||||||
if (!stream) {
|
|
||||||
perror("Erro na abertura do arquivo");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Processamento...
|
|
||||||
char line[BUFSIZ]; // Buffer para receber a linha digitada.
|
|
||||||
fgets(line, BUFSIZ, stdin); // Lê a digitação no terminal.
|
|
||||||
fprintf(stream, "%s", line) // Copia a string no buffer para o arquivo.
|
|
||||||
|
|
||||||
// Fechamento do arquivo...
|
|
||||||
fclose(stream);
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
Assim, toda vez que o programa for executado, seu conteúdo será substituído
|
|
||||||
pelo que nós digitarmos (exceto na primeira vez, quando o arquivo for criado).
|
|
||||||
|
|
||||||
*** Abertura de um arquivo para append ("a")
|
|
||||||
|
|
||||||
Para que o arquivo =linha.txt= receba novas linhas a cada execução do exemplo
|
|
||||||
anterior, basta trocar a string de modo:
|
|
||||||
|
|
||||||
#+begin_src c
|
|
||||||
// Abertura do arquivo para append...
|
|
||||||
char *file = "linha.txt";
|
|
||||||
FILE *stream = fopen(file, "a");
|
|
||||||
if (!stream) {
|
|
||||||
perror("Erro na abertura do arquivo");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Processamento...
|
|
||||||
char line[BUFSIZ]; // Buffer para receber a linha digitada.
|
|
||||||
fgets(line, BUFSIZ, stdin); // Lê a digitação no terminal.
|
|
||||||
fprintf(stream, "%s", line) // Copia a string no buffer para o arquivo.
|
|
||||||
|
|
||||||
// Fechamento do arquivo...
|
|
||||||
fclose(stream);
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
** Notas gerais
|
|
||||||
|
|
||||||
- Enquanto o arquivo estiver aberto, nós podemos realizar diversas operações
|
|
||||||
de escrita.
|
|
||||||
- No caso do modo ="w"=, o conteúdo anterior do arquivo só será truncado na
|
|
||||||
sua abertura, não a cada escrita com o arquivo já aberto.
|
|
||||||
- Toda vez que algo é escrito no arquivo, seu ponteiro interno é posicionado
|
|
||||||
no byte seguinte ao último byte escrito.
|
|
||||||
|
|
|
@ -1,93 +0,0 @@
|
||||||
#+title: Curso Básico da Linguagem C
|
|
||||||
#+subtitle: Exercícios
|
|
||||||
#+author: Blau Araujo
|
|
||||||
#+startup: show2levels
|
|
||||||
#+options: toc:3
|
|
||||||
|
|
||||||
* Exercícios da aula 15: Abertura de arquivos para escrita
|
|
||||||
|
|
||||||
- [[../../aulas/14-wfiles/README.org][Anotações da aula]]
|
|
||||||
- [[https://youtu.be/vL8vy3krcKc][Vídeo]]
|
|
||||||
|
|
||||||
** 1. Programa 'nf' (new file)
|
|
||||||
|
|
||||||
No Unix e no GNU, é comum as pessoas associarem a criação de novos arquivos
|
|
||||||
vazios ao utilitário =touch=, mas isso é só um efeito colateral de seu verdadeiro
|
|
||||||
propósito, que é alterar a data/hora de último acesso ao arquivo. Sendo assim,
|
|
||||||
crie um programa realmente dedicado a criar novos arquivos vazios.
|
|
||||||
|
|
||||||
Uso proposto:
|
|
||||||
|
|
||||||
#+begin_example
|
|
||||||
nf ARQUIVOS...
|
|
||||||
#+end_example
|
|
||||||
|
|
||||||
Notas:
|
|
||||||
|
|
||||||
- Os caminhos e nomes dos novos arquivos devem ser passados como argumentos.
|
|
||||||
- Se nenhum argumento for passado, o programa terminará com erro, imprimindo
|
|
||||||
suas informações de uso.
|
|
||||||
- Se algum dos arquivos já existir, o programa não fará nada com ele e apenas
|
|
||||||
exibirá uma mensagem em =stderr= com o seguinte formato:
|
|
||||||
|
|
||||||
#+begin_example
|
|
||||||
Arquivo NOME já existe: nada será feito!
|
|
||||||
#+end_example
|
|
||||||
|
|
||||||
- Para cada caminho inexistente, o programa deve exibir em =stderr=:
|
|
||||||
|
|
||||||
#+begin_example
|
|
||||||
O diretório DIR não existe: impossível criar ARQUIVO!
|
|
||||||
#+end_example
|
|
||||||
|
|
||||||
- Se algum arquivo não puder ser criado por falta de privilégios do usuário,
|
|
||||||
a mensagem de erro deve ser:
|
|
||||||
|
|
||||||
#+begin_example
|
|
||||||
Impossível criar ARQUIVO: acesso negado!
|
|
||||||
#+end_example
|
|
||||||
|
|
||||||
- Mesmo que algum arquivo já exista, os demais devem ser criados normalmente.
|
|
||||||
- Ao terminar, o programa deve exibir em =stdout= a quantidade de arquivos criados
|
|
||||||
no seguinte formato:
|
|
||||||
|
|
||||||
#+begin_example
|
|
||||||
Arquivos criados: NUM_ARQUIVOS_CRIADOS de NUM_DE_ARQUIVOS_SOLICITADOS
|
|
||||||
#+end_example
|
|
||||||
|
|
||||||
** 2. Programa 'hd' (here doc)
|
|
||||||
|
|
||||||
No shell do Unix e do GNU, é possível criar novos arquivos digitando seus
|
|
||||||
conteúdos com o mecanismo do /here doc/:
|
|
||||||
|
|
||||||
#+begin_example
|
|
||||||
:~$ cat << FIM >> ARQUIVO
|
|
||||||
#+end_example
|
|
||||||
|
|
||||||
Assim, o utilitário =cat= lê as linhas digitadas, imprime essas linhas e o shell
|
|
||||||
as redireciona para /append/ em =ARQUIVO=. Portanto, crie um programa que reproduza
|
|
||||||
este comportamento de forma autônoma, ou seja, sem operadores do shell.
|
|
||||||
|
|
||||||
Uso proposto:
|
|
||||||
|
|
||||||
#+begin_example
|
|
||||||
hd ARQUIVO
|
|
||||||
#+end_example
|
|
||||||
|
|
||||||
Requisitos:
|
|
||||||
|
|
||||||
- Apenas o primeiro argumento será aceito como o caminho e o nome do arquivo que
|
|
||||||
receberá as linhas digitadas no terminal.
|
|
||||||
- O programa deve avisar ao usuário se o arquivo já existir, dando a opção de
|
|
||||||
continuar com o seguinte prompt:
|
|
||||||
|
|
||||||
#+begin_example
|
|
||||||
O arquivo ARQUIVO já existe, deseja modifícá-lo (s/N)?
|
|
||||||
#+end_example
|
|
||||||
|
|
||||||
- A opção padrão, aceita com =Enter=, é =N= (não).
|
|
||||||
- Se o usuário aceitar continuar, as novas linhas devem ser escritas ao final
|
|
||||||
do arquivo.
|
|
||||||
- O programa vai parar de receber novas linhas quando o usuário teclar =Ctrl+D=.
|
|
||||||
- Antes de terminar, o programa deve exibir o conteúdo atual do arquivo.
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue