Leer archivo en cadena en C++

Jinku Hu 12 octubre 2023
  1. Usa el istreambuf_iterator para leer el archivo en una cadena en C++
  2. Usa rdbuf para leer el archivo en cadena en C++
  3. Usa fread para leer el archivo en una cadena
  4. Use read para leer el archivo en una cadena
Leer archivo en cadena en C++

Este artículo explicará varios métodos para leer el contenido del archivo en un std::string en C++.

Usa el istreambuf_iterator para leer el archivo en una cadena en C++

El istreambuf_iterator es un iterador de entrada que lee los sucesivos caracteres del objeto std::basic_streambuf. Así que podemos utilizar el istreambuf_iterator con un flujo ifstream y leer todo el contenido del archivo en una std::string.

Al principio, abrimos una ruta de archivo dada como un objeto ifstream. Entonces podemos pasar istreambuf_iterator<char>(input_file) al constructor string y obtener el objeto que necesitábamos en primer lugar. Nótese que estamos pasando directamente la sentencia constructora string para volver de la función. La salida del programa debe ser el contenido del fichero como se especifica en la variable 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);
}

Usa rdbuf para leer el archivo en cadena en C++

La función rdbuf es un método incorporado para devolver un puntero al búfer de flujo del archivo, que es útil para insertar todo el contenido del archivo usando el operador << al objeto necesario.

En el siguiente ejemplo, construimos un objeto ostringstream donde insertamos el valor de retorno de la función rdbuf. La propia función devuelve el objeto string, por lo que el método str se utiliza para obtener el 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);
}

Usa fread para leer el archivo en una cadena

Otro método para leer un archivo es la función fread de la biblioteca estándar de C. Este método requiere funciones relativamente heredadas que no son comunes en las modernas bases de código C++, pero ofrece un rendimiento de aceleración significativo en comparación con los métodos anteriores.

La fread toma cuatro argumentos:

  1. Un puntero al búfer donde se almacenan los datos leídos.
  2. El tamaño del elemento de datos.
  3. Número de elementos de datos
  4. El puntero del archivo desde el cual leer.

Ya que estamos leyendo todo el archivo, el tamaño del archivo necesita ser recuperado, y se implementa con la llamada al sistema Unix stat. Una vez que el tamaño del archivo es recuperado, pasamos su valor como el tamaño del elemento de datos a la función fread, y como el número de elementos de datos, especificamos 1.

Note que los archivos abiertos necesitan ser cerrados con la llamada a la función fclose, que toma el único argumento del puntero del archivo.

#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);
}

Use read para leer el archivo en una cadena

El método de read es una llamada de función compatible con POSIX disponible en varios sistemas operativos y puede ser el más flexible si el programador sabe emplearlo de forma eficiente. La fread en sí misma llama a la read por debajo, pero esto no garantiza una operación más rápida en todos los casos, ya que múltiples factores juegan un papel en el uso eficiente de tales llamadas de sistema.

La principal diferencia con fread es que read necesita un argumento descriptor de archivo para apuntar al archivo desde donde leer los datos. Los descriptores de archivos son enteros especiales asociados con los flujos de archivos abiertos que el programa puede tener durante la ejecución. Pueden ser adquiridos usando la llamada a la función open y almacenados en el tipo int. Los otros dos argumentos de la función read son el puntero al búfer donde se almacenarán los datos y el número de bytes necesarios para ser leídos, este último se recupera con la llamada a la función fstat. Observe que estamos usando el string.data como el buffer para almacenar el contenido del archivo de lectura.

#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

Artículo relacionado - C++ File