Necesito guardar el vector del vector en el archivo y leerlo. Intento esto con este código, pero se produce un error:

void saveVector(std::string path, vector<vector<float>> myVector)
{
    std::ofstream FILE(path, std::ios::out | std::ofstream::binary);
    std::copy(myVector.begin(), myVector.end(), std::ostreambuf_iterator<char>(FILE));
    FILE.close();
}

Error:

Error   C2679   binary '<<': no operator found which takes a right-hand operand of type 'std::vector<float,std::allocator<_Ty>>' (or there is no acceptable conversion)
1
ali kiani 5 abr. 2017 a las 14:58

2 respuestas

La mejor respuesta

En esta línea:

std::copy(myVector.begin(), myVector.end(), std::ostreambuf_iterator<char>(FILE));

Esperas que std::ostreambuf_iterator<char> sepa cómo escribir std::vector<float> en una secuencia, pero solo sabe cómo escribir o char tipo, mira su operador de asignación aquí: http://en.cppreference.com/w/cpp/iterator/ostreambuf_iterator/operator%3D

Lo haría manualmente:

http://coliru.stacked-crooked.com/a/e7e587c90069a90a

void saveVector(std::string path, const vector<vector<float> >& myVector)
{
    std::ofstream FILE(path, std::ios::out | std::ofstream::binary);

    // Store size of the outer vector
    int s1 = myVector.size();
    FILE.write(reinterpret_cast<const char *>(&s1), sizeof(s1));    

    // Now write each vector one by one
    for (auto& v : myVector) {         
        // Store its size
        int size = v.size();
        FILE.write(reinterpret_cast<const char *>(&size), sizeof(size));

        // Store its contents
        FILE.write(reinterpret_cast<const char *>(&v[0]), v.size()*sizeof(float));
    }
    FILE.close();   
}

void readVector(std::string path,  vector<vector<float> >& myVector)
{
    ifstream FILE(path, std::ios::in | std::ifstream::binary);

    int size = 0;
    FILE.read(reinterpret_cast<char *>(&size), sizeof(size));
    myVector.resize(size);
    for (int n = 0; n < size; ++n) {
        int size2 = 0;
        FILE.read(reinterpret_cast<char *>(&size2), sizeof(size2));
        float f;        
        for ( int k = 0; k < size2; ++k ) {
            FILE.read(reinterpret_cast<char *>(&f), sizeof(f));
            myVector[n].push_back(f);   
        }
    }
}

int main()
{
    std::vector<std::vector<float>> ff;
    ff.resize(10);
    ff[0].push_back(10);
    ff[0].push_back(12);
    saveVector("test.bin", ff);

    std::vector<std::vector<float>> ff2;
    readVector("test.bin", ff2);

    if (ff == ff2) {
        std::cout << "ok!";
    }
}
2
marcinj 5 abr. 2017 a las 12:19

Lo que estás haciendo allá arriba ... ¡es la peor idea del mundo! Está escribiendo datos que probablemente dependen del compilador y de la versión del compilador. Esto se debe a que un vector no contiene solo la matriz, sino otras variables, como el tamaño del vector. El orden no está especificado por el estándar y, por lo tanto, la forma binaria dependerá del compilador.

Tienes muchas opciones para evitar esto:

  1. Aplane su vector y conviértalo a vector<float>
  2. Use alguna biblioteca para serializar su objeto, como búferes de protocolo de Google o boost :: serializer
  3. Invente su propia serialización (simple) para este problema en particular (este no es el mejor, pero es mucho mejor que escribir tales estructuras en binario.

Si usa C ++ 03, debe usar el tipo: vector<vector<float> >, no vector<vector<float>>.

También pase dichos objetos por referencia para evitar copiarlos. Me gusta esto:

void saveVector(const std::string& path, const vector<vector<float>>& myVector)
4
The Quantum Physicist 5 abr. 2017 a las 12:17