Leggi il file nella stringa in C++

Jinku Hu 12 ottobre 2023
  1. Usa istreambuf_iterator per leggere il file nella stringa in C++
  2. Usa rdbuf per leggere il file in una stringa in C++
  3. Usa fread per leggere il file nella stringa
  4. Usa leggi per leggere il file nella stringa
Leggi il file nella stringa in C++

Questo articolo spiegherà diversi metodi per leggere il contenuto del file in una std::string in C++.

Usa istreambuf_iterator per leggere il file nella stringa in C++

istreambuf_iterator è un iteratore di input che legge i caratteri successivi dall’oggetto std::basic_streambuf. Quindi possiamo utilizzare istreambuf_iterator con un flusso ifstream e leggere l’intero contenuto del file in uno std::string.

All’inizio, apriamo un determinato percorso di file come oggetto ifstream. Quindi possiamo passare istreambuf_iterator<char>(input_file) al costruttore string e ottenere l’oggetto di cui avevamo bisogno in primo luogo. Notare che stiamo passando direttamente l’istruzione del costruttore string per tornare dalla funzione. L’output del programma dovrebbe essere il contenuto del file come specificato dalla variabile 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 per leggere il file in una stringa in C++

La funzione rdbuf è un metodo integrato per restituire un puntatore al buffer di flusso del file, che è utile per inserire l’intero contenuto del file utilizzando l’operatore << all’oggetto necessario.

Nell’esempio seguente, costruiamo un oggetto ostringstream dove inseriamo il valore di ritorno della funzione rdbuf. La funzione stessa restituisce l’oggetto string, quindi il metodo str viene utilizzato per ottenere il valore di ritorno finale.

#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 per leggere il file nella stringa

Un altro metodo per leggere un file è la funzione di libreria standard C fread. Questo metodo richiede funzioni relativamente legacy che non sono comuni nelle moderne codebase C++, ma offre prestazioni di accelerazione significative rispetto ai metodi precedenti.

fread richiede quattro argomenti:

  1. Un puntatore al buffer in cui sono memorizzati i dati letti.
  2. La dimensione dell’elemento di dati.
  3. Numero di elementi di dati
  4. Il puntatore del file da cui leggere.

Dato che stiamo leggendo l’intero file, la dimensione del file deve essere recuperata, ed è implementata con la chiamata di sistema Unix stat. Una volta recuperata la dimensione del file, passiamo il suo valore come dimensione dell’elemento di dati alla funzione fread e come numero di elementi di dati, specifichiamo 1.

Nota che i file aperti devono essere chiusi con la chiamata alla funzione fclose, che accetta l’unico argomento del puntatore del file.

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

Usa leggi per leggere il file nella stringa

Il metodo read è una chiamata di funzione conforme a POSIX disponibile su vari sistemi operativi e può essere il più flessibile se il programmatore sa come utilizzarlo in modo efficiente. fread stesso chiama read sotto, ma questo non garantisce l’operazione più veloce in tutti i casi, poiché molteplici fattori giocano un ruolo nell’uso efficiente di tali chiamate di sistema.

La differenza principale con fread è che read necessita di un argomento descrittore di file per puntare al file da cui leggere i dati. I descrittori di file sono numeri interi speciali associati ai flussi di file aperti che il programma potrebbe avere durante l’esecuzione. Può essere acquisito tramite la chiamata alla funzione open e memorizzato nel tipo int. Gli altri due argomenti della funzione read sono il puntatore al buffer dove verranno memorizzati i dati e il numero di byte necessari per essere letti, l’ultimo dei quali viene recuperato con la chiamata alla funzione fstat. Notare che stiamo usando string.data come buffer per memorizzare il contenuto del file letto.

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

Articolo correlato - C++ File