salvare - scrivere array su file c++




Leggi il file riga per riga usando ifstream in C++ (5)

Dal momento che le tue coordinate appartengono insieme come coppie, perché non scrivere una struttura per loro?

#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <fcntl.h>

namespace io = boost::iostreams;

void readLineByLineBoost() {
    int fdr = open(FILENAME, O_RDONLY);
    if (fdr >= 0) {
        io::file_descriptor_source fdDevice(fdr, io::file_descriptor_flags::close_handle);
        io::stream <io::file_descriptor_source> in(fdDevice);
        if (fdDevice.is_open()) {
            std::string line;
            while (std::getline(in, line)) {
                // using printf() in all tests for consistency
                printf("%s", line.c_str());
            }
            fdDevice.close();
        }
    }
}

Quindi puoi scrivere un operatore di estrazione sovraccarico per istanze:

FILE* fp = fopen(FILENAME, "r");
if (fp == NULL)
    exit(EXIT_FAILURE);

char* line = NULL;
size_t len = 0;
while ((getline(&line, &len, fp)) != -1) {
    // using printf() in all tests for consistency
    printf("%s", line);
}
fclose(fp);
if (line)
    free(line);

E poi puoi leggere un file di coordinate direttamente in un vettore come questo:

                             10K lines     100K lines     1000K lines
Loop with std::getline()         105ms          894ms          9773ms
Boost code                       106ms          968ms          9561ms
C code                            23ms          243ms          2397ms

I contenuti di file.txt sono:

5 3
6 4
7 1
10 5
11 6
12 3
12 4

Dove 5 3 è una coppia di coordinate. Come posso elaborare questo dato riga per riga in C ++?

Sono in grado di ottenere la prima riga, ma come faccio a ottenere la riga successiva del file?

ifstream myfile;
myfile.open ("text.txt");

Espansione sulla risposta accettata, se l'input è:

1,NYC
2,ABQ
...

sarai ancora in grado di applicare la stessa logica, come questa:

#include <fstream>

std::ifstream infile("thefile.txt");
if (infile.is_open()) {
    int number;
    std::string str;
    char c;
    while (infile >> number >> c >> str && c == ',')
        std::cout << number << " " << str << "\n";
}
infile.close();

La lettura di un file riga per riga in C ++ può essere eseguita in diversi modi.

[Fast] Loop con std :: getline ()

L'approccio più semplice è quello di aprire uno std :: ifstream e loop usando le chiamate std :: getline (). Il codice è pulito e facile da capire.

struct CoordinatePair
{
    int x;
    int y;
};

[Veloce] Usa Boost's file_description_source

Un'altra possibilità è usare la libreria Boost, ma il codice diventa un po 'più dettagliato. Le prestazioni sono abbastanza simili al codice precedente (Loop con std :: getline ()).

std::istream& operator>>(std::istream& is, CoordinatePair& coordinates)
{
    is >> coordinates.x >> coordinates.y;

    return is;
}

[Più veloce] Usa il codice C

Se le prestazioni sono fondamentali per il tuo software, puoi prendere in considerazione l'utilizzo del linguaggio C. Questo codice può essere 4-5 volte più veloce rispetto alle versioni C ++ sopra, vedi benchmark sotto

#include <fstream>
#include <iterator>
#include <vector>

int main()
{
    char filename[] = "coordinates.txt";
    std::vector<CoordinatePair> v;
    std::ifstream ifs(filename);
    if (ifs) {
        std::copy(std::istream_iterator<CoordinatePair>(ifs), 
                std::istream_iterator<CoordinatePair>(),
                std::back_inserter(v));
    }
    else {
        std::cerr << "Couldn't open " << filename << " for reading\n";
    }
    // Now you can work with the contents of v
}

Benchmark - Quale è più veloce?

Ho fatto alcuni benchmark delle prestazioni con il codice sopra e i risultati sono interessanti. Ho testato il codice con file ASCII che contengono 100.000 righe, 1.000.000 di righe e 10.000.000 di righe di testo. Ogni riga di testo contiene in media 10 parole. Il programma viene compilato con -O3 ottimizzazione -O3 e il suo output viene inoltrato a /dev/null per rimuovere la variabile del tempo di registrazione dalla misura. Ultimo, ma non meno importante, ogni pezzo di codice registra ogni riga con la printf() per coerenza.

I risultati mostrano il tempo (in ms) che ciascun pezzo di codice ha impiegato per leggere i file.

La differenza di prestazioni tra i due approcci C ++ è minima e non dovrebbe fare alcuna differenza nella pratica. Le prestazioni del codice C sono ciò che rende il benchmark impressionante e può essere un punto di svolta in termini di velocità.

#include <fstream>

std::ifstream file(FILENAME);
if (file.is_open()) {
    std::string line;
    while (getline(file, line)) {
        // using printf() in all tests for consistency
        printf("%s", line.c_str());
    }
    file.close();
}


Sebbene non sia necessario chiudere manualmente il file, è consigliabile farlo se l'ambito della variabile file è maggiore:

    ifstream infile(szFilePath);

    for (string line = ""; getline(infile, line); )
    {
        //do something with the line
    }

    if(infile.is_open())
        infile.close();

con gli argomenti della riga di comando:

#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include "print.h"

using namespace std;

int main (int argc, char *argv[]) 
{
    vector<string> list;
    ifstream in_stream;
    string line;
    in_stream.open(argv[1]);

    while(!in_stream.eof())
    {
        in_stream >> line;
        list.push_back(line);
    }
    in_stream.close();
    print(list);
    sort(list.begin(), list.end());
    print(list);
}




ofstream