diff --git a/aulas/15-wfiles/README.org b/aulas/15-wfiles/README.org new file mode 100644 index 0000000..1ad8982 --- /dev/null +++ b/aulas/15-wfiles/README.org @@ -0,0 +1,124 @@ +#+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. +