Ler Ficheiro em Strings em C++
-
Utilizar
istreambuf_iterator
para ler o conteúdo do ficheiro em C++ em C+ -
Utilizar o
rdbuf
para ler o ficheiro em String em C++ -
Utilizar o
fread
para ler o ficheiro em String -
Utilize a função
read
para ler o ficheiro em String
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:
- Um ponteiro para o buffer onde os dados lidos são armazenados.
- O tamanho do item de dados.
- Número de itens de dados
- 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);
}
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