Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling map of files in c++

Tags:

c++

I need to write to a bunch of files simultaneously, so I decided to use map <string, ofstream>.

map<string, ofstream> MyFileMap; 

I take a vector<string> FileInd, which consists of, say "a" "b" "c", and try to open my files with:

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

I get the error

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

I've tried to switch to

map<string, ofstream*> MyFileMap;

But it didn't work either.

Could anyone help?

Thanks.

Clarification:

I've tried both

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

with both

.open ->open

neither of 4 variants work.

Solution (suggested in Rob's code below):

Basically, I forgot "new", the following works for me:

map<string, ofstream*> MyFileMap;
MyFileMap[*it] = new ofstream("/myhomefolder/"+(*it)+".");
like image 210
LazyCat Avatar asked Feb 04 '12 05:02

LazyCat


People also ask

What is a map file in C?

A mapfile is a text file that contains the following information about the program being linked: The module name, which is the base name of the file. The timestamp from the program file header (not from the file system)

Can you use a map in C?

The C Programming Language by Kernighan and Ritchie has an example of making an associate map in c, and what I'll detail below is based on what I remember from that. Basically you'll need a struct Map that contains struct Key and struct Value.

What is the use of .map file?

More generically, the . MAP extension can be used to denote any file type that indicates relative offsets from a starting point. MAP file types are used in this way, for example, when variables in software are expected to be "mapped" to a specific spot in memory.

How do I view a .map file?

You can open a MAP file with Valve Hammer Editor (Windows), Chain Studios J.A.C.K. (multiplatform), Quark (Windows), and many other Quake engine-related development and modding programs. You can also open a MAP file with any text editor to view the plain text data it contains.


1 Answers

std::map<std::string, std::ofstream> can't possibly work, because std::map requires its data type to be Assignable, which std::ofstream isn't. In the alternative, the data type must be a pointer to ofstream -- either a raw pointer or a smart pointer.

Here is how I would do it, using C++11 features:

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

and the 2nd verse, in 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;
  }
}
like image 185
Robᵩ Avatar answered Nov 02 '22 12:11

Robᵩ