2012-02-04 36 views
6

Tôi cần phải ghi vào một loạt tệp cùng một lúc, vì vậy tôi quyết định sử dụng map <string, ofstream>.Xử lý bản đồ tệp trong C++

map<string, ofstream> MyFileMap; 

Tôi lấy một vector<string> FileInd, trong đó bao gồm, nói "a" "b" "c", và cố gắng để mở tập tin của tôi với:

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

tôi nhận được lỗi

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

Tôi đã cố gắng để chuyển sang

map<string, ofstream*> MyFileMap; 

Nhưng nó cũng không hoạt động.

Có ai giúp được không?

Cảm ơn.

Làm rõ:

Tôi đã thử cả hai

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

với cả

.open ->open

cả 4 biến thể đều không hoạt động.

Solution (gợi ý trong mã của Rob dưới đây):

Về cơ bản, tôi quên mất "mới", các công việc sau cho tôi:

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

Bạn muốn '-> open' , không phải '.open'. Toán tử '[] trên một vectơ trả về một cái gì đó hoạt động giống như một con trỏ, không phải là một tham chiếu. –

+0

@DavidSchwartz Không theo http://www.cplusplus.com/reference/stl/map/operator%5B%5D/ – Borealid

+0

Xin lỗi, tôi có nghĩa là trên một 'bản đồ', không phải trên' vectơ'. –

Trả lời

8

std::map<std::string, std::ofstream> có thể không có khả năng làm việc, bởi vì std::map đòi hỏi loại dữ liệu của nó sẽ được gán, trong đó std::ofstream thì không. Thay vào đó, kiểu dữ liệu phải là một con trỏ đến luồng - hoặc là một con trỏ thô hoặc một con trỏ thông minh.

Dưới đây là làm thế nào tôi sẽ làm điều đó, sử dụng C++ 11 tính năng:

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

và câu thứ 2, trong 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

Cảm ơn bạn đã trả lời nhanh và một ví dụ gọn gàng. Tôi quên "mới". – LazyCat

+0

như cppcoreguidelines đề nghị con trỏ thô không được recommanded như thực hành tốt nhất. Còn cách nào khác không? –