Leer archivo en cadena en C++
-
Usa el
istreambuf_iterator
para leer el archivo en una cadena en C++ -
Usa
rdbuf
para leer el archivo en cadena en C++ -
Usa
fread
para leer el archivo en una cadena -
Use
read
para leer el archivo en una cadena
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:
- Un puntero al búfer donde se almacenan los datos leídos.
- El tamaño del elemento de datos.
- Número de elementos de datos
- 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);
}
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