Da trilha de C Este conceito ainda não saiu como card do dia. ir para o card de hoje

C Erros Intermediário

Tratamento de erros

Em C, o tratamento de erros é manual e explícito. Diferente de linguagens com exceções, funções sinalizam falhas por códigos de retorno, pela variável global errno ou por assert. O programador deve verificar cada chamada que pode falhar e decidir o que fazer.

A biblioteca padrão usa errno para indicar o motivo exato da falha. Após uma chamada que retorna erro, você pode inspecionar errno ou usar perror para imprimir uma mensagem legível. É importante zerar errno antes da chamada, pois ele só é modificado em caso de erro.

Para bugs de programação, assert é útil: ele aborta o programa se a condição for falsa. Já para liberar recursos em cascata (memória, arquivos, sockets), o padrão goto com um bloco de limpeza é idiomático em C e evita vazamentos e código duplicado.

Pontos-chave

  • Funções da biblioteca padrão retornam valores especiais (NULL, -1, 0) para indicar erro; sempre verifique.
  • errno é uma variável global que armazena o código do último erro; use perror para uma mensagem descritiva.
  • assert(condicao) aborta o programa se a condição for falsa; use apenas para bugs internos, não para validar entrada do usuário.
  • O padrão goto cleanup centraliza a liberação de recursos e evita vazamentos em múltiplos pontos de falha.
  • Sempre inicialize errno = 0 antes de chamar uma função que pode falhar, para não confundir erros antigos.
tratamento_erros.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <assert.h>

// Função que aloca memória e copia string, tratando erros
char *duplica_string(const char *origem) {
    assert(origem != NULL); // bug interno se origem for NULL
    size_t tam = strlen(origem) + 1;
    char *copia = malloc(tam);
    if (copia == NULL) {
        perror("malloc falhou"); // imprime mensagem do errno
        return NULL;
    }
    memcpy(copia, origem, tam);
    return copia;
}

int main(void) {
    errno = 0; // zera errno antes de operações que podem falhar
    char *s = duplica_string("Olá, mundo!");
    if (s == NULL) {
        fprintf(stderr, "Erro ao duplicar string.\n");
        return EXIT_FAILURE;
    }
    printf("String duplicada: %s\n", s);
    free(s);
    return EXIT_SUCCESS;
}

Exercícios

  1. 1
    Fácil

    Verificando abertura de arquivo

    Escreva um programa que tente abrir o arquivo dados.txt para leitura. Se a abertura falhar, use perror para mostrar o erro e retorne EXIT_FAILURE. Se abrir com sucesso, feche o arquivo e retorne EXIT_SUCCESS.

    Resolver
  2. 2
    Médio

    Alocação de matriz com limpeza com goto

    Implemente uma função que aloca uma matriz de inteiros com linhas x colunas. Use malloc para o vetor de ponteiros e para cada linha. Se qualquer alocação falhar, libere toda a memória já alocada usando goto cleanup e retorne NULL. Se tudo der certo, retorne o ponteiro para a matriz.

    Resolver
  3. 3
    Desafio

    Cópia de arquivo com verificação de erros e assert

    Implemente um programa que copia o conteúdo de um arquivo de origem para um destino. O programa deve receber dois argumentos de linha de comando: origem e destino. Use assert para garantir que argc == 3. Abra a origem para leitura e o destino para escrita. Se qualquer abertura falhar, use perror e retorne EXIT_FAILURE. Copie os dados em blocos de 4096 bytes, verificando erros de leitura e escrita. Ao final, feche ambos os arquivos e retorne EXIT_SUCCESS.

    Resolver

Continue estudando