Carregando
0xD0Lição 14 de 20

Trabalhando com arquivos

Abra, leia e escreva arquivos com a API FILE e trate os erros que os arquivos reais jogam em você.

14 min Questionário com 5 perguntas 1 exercício de código
Ao final desta lição, você saberá
  • Abrir e fechar arquivos com fopen e fclose
  • Ler linha por linha com fgets e escrever com fprintf
  • Tratar os erros quando um arquivo não pode ser aberto

Os programas ficam úteis quando os dados deles sobrevivem a eles. O C trabalha com arquivos por meio de um FILE * - um ponteiro para um objeto que acompanha um arquivo aberto. Você já vem usando três deles sem saber: stdin, stdout e stderr são valores FILE * que são abertos para você.

Abrindo e fechando

write_notes.c
1#include <stdio.h>
2
3int main(void) {
4    FILE *file = fopen("notes.txt", "w");
5    if (file == NULL) {
6        perror("notes.txt");
7        return 1;
8    }
9
10    fprintf(file, "Buy milk\n");
11    fprintf(file, "Learn pointers\n");
12
13    fclose(file);
14    return 0;
15}

fopen(path, mode) devolve um FILE *, ou NULL se o arquivo não pôde ser aberto (arquivo inexistente, sem permissão, caminho errado). Os modos comuns:

ModoSignificado
"r"ler um arquivo existente
"w"escrever - cria o arquivo ou apaga um existente
"a"acrescentar no fim, criando o arquivo se preciso

O perror imprime a sua mensagem mais o motivo da falha da última chamada (por exemplo, notes.txt: No such file or directory). O fclose descarrega o que ainda estiver em buffer e libera o arquivo - sempre feche o que você abrir.

Lendo linha por linha

fgets(buffer, size, file) lê uma linha de cada vez e devolve NULL no fim do arquivo, o que dá um laço limpo. Como o stdin também é um FILE *, uma função que recebe um FILE * funciona com arquivos reais e com entrada digitada - que é exatamente como os exercícios daqui rodam.

number_lines.c
1#include <stdio.h>
2
3void number_lines(FILE *input) {
4    char line[256];
5    int number = 1;
6    while (fgets(line, sizeof line, input) != NULL) {
7        printf("%3d | %s", number, line);
8        number++;
9    }
10}
11
12int main(int argc, char *argv[]) {
13    if (argc < 2) {
14        number_lines(stdin);
15        return 0;
16    }
17    FILE *file = fopen(argv[1], "r");
18    if (file == NULL) {
19        perror(argv[1]);
20        return 1;
21    }
22    number_lines(file);
23    fclose(file);
24    return 0;
25}

Este programa também mostra argumentos de linha de comando: main(int argc, char *argv[]) recebe as palavras digitadas depois do nome do programa. ./number_lines notes.txt faz argv[1] ser a string "notes.txt". Sem argumento, ele lê a entrada padrão - um desenho muito amigável ao Unix.

Lendo dados formatados

fscanf(file, format, ...) é o scanf para qualquer arquivo, e fprintf(file, format, ...) é o printf para qualquer arquivo. fprintf(stderr, ...) é o jeito padrão de imprimir mensagens de erro: elas vão para um fluxo separado, então não se misturam com a saída que é redirecionada para outro programa.

Principais conclusões

  • O fopen dá um FILE * ou NULL - sempre verifique. Faça fclose de tudo o que você abrir.

  • "r" lê, "w" cria ou apaga, "a" acrescenta.

  • Leia as linhas com fgets até ele devolver NULL. As funções que recebem um FILE * funcionam igualmente bem com o stdin.

Quiz da aula

5 perguntas · aprovação com 4 acertos · até 50 XP

Ao passar, você conclui a aula e mantém sua sequência. As perguntas erradas voltarão em sessões de revisão.

Pratique: escreva código em C

Estes exercícios rodam de verdade. Escreva o programa, clique em “Executar testes” e leia o que o compilador informa: aprender a ler as mensagens do compilador é metade do aprendizado de C.

Exercício 1

wc, a versão minúscula

+25 XP

Escreva void count(FILE *input, int *lines, int *words, int *chars), que conta linhas, palavras e caracteres, como a ferramenta wc do Unix. Uma palavra é uma sequência de caracteres que não são espaço em branco. A main a chama com stdin e imprime as três contagens separadas por espaços.

Para a entrada the quick fox seguida de uma quebra de linha, a saída é 1 3 14.

  • Uma linha
  • Espaços extras
main.c
Carregando editor…

Seu código é compilado com gcc 14 (-Wall -Wextra) e executado no Compiler Explorer (godbolt.org), um serviço público gratuito.

Dúvidas sobre esta lição

Travou em algum ponto? Pergunte. Descobriu algo? Compartilhe. Explicar também é uma ótima forma de aprender.

Carregando publicações…