2012-02-04 22 views
6

Necesito escribir en un grupo de archivos simultáneamente, así que decidí usar map <string, ofstream>.Manejo del mapa de archivos en C++

map<string, ofstream> MyFileMap; 

Tomo una vector<string> FileInd, que consta de, por ejemplo "a" "b" "c", y tratar de abrir los archivos con:

for (vector<string>::iterator it = FileInd.begin(); iter != FileInd.end(); ++it){ 
    ... 
    MyFileMap[*it].open("/myhomefolder/"+(*it)+"."); 
} 

consigo el error

request for member 'open' in ..... , which is of non-class type 'std::ofstream*' 

He tratado de cambiar a

map<string, ofstream*> MyFileMap; 

Pero tampoco funcionó.

¿Alguien podría ayudar?

Gracias.

Aclaración:

He intentado tanto

map<string, ofstream> MyFileMap; map<string, ofstream*> MyFileMap;

tanto con

.open ->open

ninguna de las 4 variantes funciona.

Solution (se sugiere en el código de Rob abajo):

Básicamente, se me olvidó "nuevas", las siguientes obras para mí:

map<string, ofstream*> MyFileMap; 
MyFileMap[*it] = new ofstream("/myhomefolder/"+(*it)+"."); 
+0

Quiere '-> open' , no '.open'. El operador '[]' en un vector devuelve algo que actúa como un puntero, no como una referencia. –

+0

@DavidSchwartz No de acuerdo con http://www.cplusplus.com/reference/stl/map/operator%5B%5D/ – Borealid

+0

Lo siento, quise decir en un 'mapa', no en un' vector'. –

Respuesta

8

std::map<std::string, std::ofstream> no es posible que el trabajo, porque std::map requiere su tipo de datos es Asignable, que no es std::ofstream. En la alternativa, el tipo de datos debe ser un puntero a ofstream, ya sea un puntero sin formato o un puntero inteligente.

Aquí es cómo lo haría, usando C++ 11 características:

#include <string> 
#include <map> 
#include <fstream> 
#include <iostream> 
#include <vector> 

int main (int ac, char **av) 
{ 
    // Convenient access to argument array 
    std::vector<std::string> fileNames(av+1, av+ac); 

    // If I were smart, this would be std::shared_ptr or something 
    std::map<std::string, std::ofstream*> fileMap; 

    // Open all of the files 
    for(auto& fileName : fileNames) { 
    fileMap[fileName] = new std::ofstream("/tmp/xxx/"+fileName+".txt"); 
    if(!fileMap[fileName] || !*fileMap[fileName]) 
     perror(fileName.c_str()); 
    } 

    // Write some data to all of the files 
    for(auto& pair : fileMap) { 
    *pair.second << "Hello, world\n"; 
    } 

    // Close all of the files 
    // If I had used std::shared_ptr, I could skip this step 
    for(auto& pair : fileMap) { 
    delete pair.second; 
    pair.second = 0; 
    } 
} 

y el segundo verso, en C++ 03:

#include <string> 
#include <map> 
#include <fstream> 
#include <iostream> 
#include <vector> 

int main (int ac, char **av) 
{ 
    typedef std::map<std::string, std::ofstream*> Map; 
    typedef Map::iterator Iterator; 

    Map fileMap; 

    // Open all of the files 
    std::string xxx("/tmp/xxx/"); 
    while(av++,--ac) { 
    fileMap[*av] = new std::ofstream((xxx+*av+".txt").c_str()); 
    if(!fileMap[*av] || !*fileMap[*av]) 
     perror(*av); 
    } 

    // Write some data to all of the files 
    for(Iterator it = fileMap.begin(); it != fileMap.end(); ++it) { 
    *(it->second) << "Hello, world\n"; 
    } 

    // Close all of the files 
    for(Iterator it = fileMap.begin(); it != fileMap.end(); ++it) { 
    delete it->second; 
    it->second = 0; 
    } 
} 
+0

Gracias por una pronta respuesta y un buen ejemplo. Olvidé "nuevo". – LazyCat

+0

ya que las guías de configuración de CPP sugieren que el puntero sin formato no se recomiende como la mejor práctica. ¿Hay alguna otra manera? –