Lendo arquivo linha por linha em C++: ifstream e 5 erros fatais

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Por que a simples leitura de arquivo em C++ quebra o código até de experientes?

\n\n

Imagine a situação: você está escrevendo um parser de configs, logs ou CSV. Tudo parece elementar — abrir o arquivo, ler linha por linha, processar. Mas na realidade, no Stack Overflow a pergunta "Read file line by line using ifstream in C++" acumula milhares de visualizações e centenas de comentários. Por quê? Porque o diabo, como sempre, está nos detalhes.

\n\n

Neste artigo, não vamos apenas mostrar como ler um arquivo linha por linha corretamente. Vamos analisar os 5 erros mais comuns e perigosos que transformam código funcional em um monte de bugs. Você vai descobrir por que while (!file.eof()) é um mal, como não perder a última linha e o que fazer com arquivos binários. Vamos lá!

\n\n

Sintaxe básica: como abrir um arquivo e ler uma linha

\n\n

Vamos começar com o básico. A classe std::ifstream (input file stream) é sua principal ferramenta para ler arquivos. Aqui está um exemplo funcional mínimo:

\n\n
#include <iostream>\n#include <fstream>\n#include <string>\n\nint main() {\n    std::ifstream file("example.txt");\n    std::string line;\n\n    if (file.is_open()) {\n        while (std::getline(file, line)) {\n            std::cout << line << std::endl;\n        }\n        file.close();\n    } else {\n        std::cerr << "Erro ao abrir o arquivo!" << std::endl;\n    }\n    return 0;\n}
\n\n

Parece que algo pode dar errado? E dá.

\n\n

Erro nº1: Usar while (!file.eof())

\n\n

Esta é, provavelmente, a armadilha mais popular para iniciantes. Parece lógico: "enquanto não for o fim do arquivo — leia". Mas o problema é:

\n\n
    \n
  • eof() retorna true apenas após uma tentativa de leitura mal-sucedida.
  • \n
  • O loop será executado uma iteração a mais do que o necessário.
  • \n
  • A última linha será processada duas vezes ou você receberá dados lixo.
  • \n
\n\n

Exemplo-catástrofe:

\n\n
std::ifstream file("data.txt");\nstd::string line;\n\nwhile (!file.eof()) {  // NUNCA FAÇA ISSO!\n    std::getline(file, line);\n    std::cout << line << std::endl;  // A última linha será exibida duas vezes\n}
\n\n

Solução correta: use std::getline na condição do loop, como no primeiro exemplo. Ele retorna o próprio fluxo, que é convertido para bool: true se a leitura for bem-sucedida, e false em caso de erro ou fim do arquivo.

\n\n

Erro nº2: Ignorar a verificação de abertura do arquivo

\n\n

Parece óbvio, mas milhares de linhas de código no GitHub falham com segmentation fault exatamente por causa disso. Se o arquivo não existir ou não houver permissão de leitura, o ifstream não lançará uma exceção — ele simplesmente ficará em um estado "quebrado".

\n\n

Incorreto:

\n\n
std::ifstream file("nonexistent.txt");\nstd::string line;\nwhile (std::getline(file, line)) {  // Opa! O arquivo não foi aberto\n    // Este código nunca será executado\n}
\n\n

O problema é que você não saberá do erro. Os dados estarão vazios e a lógica do programa será quebrada.

\n\n

Correto:

\n\n
std::ifstream file("data.txt");\nif (!file) {\n    std::cerr << "Não foi possível abrir o arquivo!" << std::endl;\n    return 1;\n}\n// Em seguida, a leitura
\n\n

Use if (!file) ou if (!file.is_open()) — não há diferença, ambos verificam o estado do fluxo.

\n\n

Erro nº3: Esquecer dos espaços e delimitadores

\n\n

O operador >> (extração) lê até o primeiro espaço. Se você usá-lo em vez de std::getline, corre o risco de obter algo diferente do esperado.

\n\n

Exemplo: o arquivo contém a string "Hello World".

\n\n
std::string word;\nfile >> word;  // Lerá apenas "Hello"\n// word == "Hello"

Blogs

Book Recommendations