Ler Ficheiro em Strings em C++

Jinku Hu 12 outubro 2023
  1. Utilizar istreambuf_iterator para ler o conteúdo do ficheiro em C++ em C+
  2. Utilizar o rdbuf para ler o ficheiro em String em C++
  3. Utilizar o fread para ler o ficheiro em String
  4. Utilize a função read para ler o ficheiro em String
Ler Ficheiro em Strings em C++

Este artigo explicará vários métodos de leitura do conteúdo do ficheiro num std::string em C++.

Utilizar istreambuf_iterator para ler o conteúdo do ficheiro em C++ em C+

istreambuf_iterator é um iterador de inteiro que lê caracteres sucessivos do objecto std::basic_streambuf. Assim, podemos utilizar o istreambuf_iterator com um fluxo ifstream e ler todo o conteúdo do ficheiro para um std::string.

No início, abrimos um determinado caminho do ficheiro como um objecto ifstream. Depois podemos passar o istreambuf_iterator<char>(input_file) ao construtor do string e obter o objecto de que precisávamos em primeiro lugar. Note-se que estamos a passar directamente a declaração do construtor string para regressar da função. A saída do programa deve ser o conteúdo do ficheiro, conforme especificado pela variável filename.

#include <fstream>
#include <iostream>
#include <sstream>

using std::cerr;
using std::cout;
using std::endl;
using std::ifstream;
using std::ostringstream;
using std::string;

string readFileIntoString(const string& path) {
  ifstream input_file(path);
  if (!input_file.is_open()) {
    cerr << "Could not open the file - '" << path << "'" << endl;
    exit(EXIT_FAILURE);
  }
  return string((std::istreambuf_iterator<char>(input_file)),
                std::istreambuf_iterator<char>());
}

int main() {
  string filename("input.txt");
  string file_contents;

  file_contents = readFileIntoString(filename);
  cout << file_contents << endl;

  exit(EXIT_SUCCESS);
}

Utilizar o rdbuf para ler o ficheiro em String em C++

A função rdbuf é um método integrado para devolver um ponteiro ao buffer de fluxo do ficheiro, que é útil para inserir todo o conteúdo do ficheiro utilizando o operador << no objecto necessário.

No exemplo seguinte, construímos um objecto de ostringstream onde inserimos o valor de retorno da função rdbuf. A própria função retorna o objecto string, pelo que o método str é utilizado para obter o valor de retorno final.

#include <fstream>
#include <iostream>
#include <sstream>

using std::cerr;
using std::cout;
using std::endl;
using std::ifstream;
using std::ostringstream;
using std::string;

string readFileIntoString2(const string& path) {
  auto ss = ostringstream{};
  ifstream input_file(path);
  if (!input_file.is_open()) {
    cerr << "Could not open the file - '" << path << "'" << endl;
    exit(EXIT_FAILURE);
  }
  ss << input_file.rdbuf();
  return ss.str();
}

int main() {
  string filename("input.txt");
  string file_contents;

  file_contents = readFileIntoString2(filename);
  cout << file_contents << endl;

  exit(EXIT_SUCCESS);
}

Utilizar o fread para ler o ficheiro em String

Outro método de leitura de um ficheiro é a função de biblioteca padrão C fread. Este método requer funções relativamente herdadas que não são comuns nas modernas bases de códigos C++, mas oferece um desempenho de aceleração significativo em comparação com os métodos anteriores.

O fread aceita quatro argumentos:

  1. Um ponteiro para o buffer onde os dados lidos são armazenados.
  2. O tamanho do item de dados.
  3. Número de itens de dados
  4. O ponteiro do ficheiro a partir do qual ler.

Uma vez que estamos a ler o ficheiro inteiro, o tamanho do ficheiro precisa de ser recuperado, e é implementado com a chamada de sistema Unix stat. Uma vez recuperado o tamanho do ficheiro, passamos o seu valor como o tamanho do elemento de dados para a função fread, e como o número de itens de dados, especificamos 1.

Note que os ficheiros abertos precisam de ser fechados com a chamada de função fclose, que toma o único argumento do ponteiro do ficheiro.

#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>

#include <iostream>

using std::cerr;
using std::cout;
using std::endl;
using std::string;

string readFileIntoString3(const string& path) {
  struct stat sb {};
  string res;

  FILE* input_file = fopen(path.c_str(), "r");
  if (input_file == nullptr) {
    perror("fopen");
  }

  stat(path.c_str(), &sb);
  res.resize(sb.st_size);
  fread(const_cast<char*>(res.data()), sb.st_size, 1, input_file);
  fclose(input_file);

  return res;
}

int main() {
  string filename("input.txt");
  string file_contents;

  file_contents = readFileIntoString3(filename);
  cout << file_contents << endl;

  exit(EXIT_SUCCESS);
}

Utilize a função read para ler o ficheiro em String

O método read é a chamada de função compatível com POSIX disponível em vários sistemas operacionais e pode ser o mais flexível se o programador souber empregá-lo eficientemente. O próprio fread chama read por baixo, mas isto não garante o funcionamento mais rápido em todos os casos, uma vez que múltiplos factores jogam uma mão na utilização eficiente de tais chamadas de sistema.

A principal diferença com o fread é que a read precisa de um argumento descritor de ficheiro para apontar para o ficheiro a partir de onde ler os dados. Os descritores de ficheiro são inteiros especiais associados aos fluxos de ficheiros abertos que o programa pode ter durante a execução. Podem ser adquiridos utilizando a função open e armazenados em tipo int. Os outros dois argumentos da função read são o ponteiro para o buffer onde os dados serão armazenados e o número de bytes necessários para serem lidos, o último dos quais é recuperado com a chamada de função fstat. Note-se que estamos a utilizar o string.data como buffer para armazenar o conteúdo do ficheiro lido.

#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>

#include <iostream>

using std::cerr;
using std::cout;
using std::endl;
using std::string;

string readFileIntoString4(const string& path) {
  struct stat sb {};
  string res;

  int fd = open(path.c_str(), O_RDONLY);
  if (fd < 0) {
    perror("open\n");
  }

  fstat(fd, &sb);
  res.resize(sb.st_size);
  read(fd, (char*)(res.data()), sb.st_size);
  close(fd);

  return res;
}

int main() {
  string filename("input.txt");
  string file_contents;

  file_contents = readFileIntoString4(filename);
  cout << file_contents << endl;

  exit(EXIT_SUCCESS);
}
Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Artigo relacionado - C++ File