Написание C ++ карты кортежа и установки в файл - PullRequest
2 голосов
/ 08 февраля 2020

у меня есть неупорядоченная карта, состоящая из кортежей в качестве ключей и устанавливаемых в качестве значений.

Как мне записать это hash_DICT в файл?

#include <tuple>
#include <map>
#include <set>

int main() {
   // Create dict here
   map <tuple<int,int,int>,set<int>> hash_DICT;
   for(int i =0; i < 10; i++){
      tuple<int,int,int> tup_key = {i, i, i};
      set<int> set_val = {i};
      hash_DICT[tup_key] = set_val;
   }
   // Write hash_DICT to file here
   return 0;
}

Адаптация от https://www.stev.org/post/cppreadwritestdmaptoafile:

int WriteFile(std::string fname, std::map<std::tuple<int,int,int>,std::set<int>> *m) {
    int count = 0;
    if (m->empty())
            return 0;

    FILE *fp = fopen(fname.c_str(), "w");
    if (!fp)
            return -errno;

    for(std::map<std::tuple<int,int,int>,std::set<int>>::iterator it = m->begin(); it != m->end(); it++) {
            fprintf(fp, "%s=%s\n", it->first.c_str(), it->second.c_str());
            count++;
    }

    fclose(fp);
    return count;
}

Но ошибки заключаются в следующем:

class "std::tuple<int, int, int>" has no member "c_str"
class "std::set<int, std::less<int>, std::allocator<int>>" has no member "c_str"

Как мне их изменить уметь писать в файл и читать их тоже?

1 Ответ

1 голос
/ 08 февраля 2020

Посмотрите на ошибки:

class "std::tuple<int, int, int>" has no member "c_str"
class "std::set<int, std::less<int>, std::allocator<int>>" has no member "c_str"

Эти ошибки говорят сами за себя c_str() - это функция, которая дает const char * (или строк в c), поскольку вы следовали уроку, они использовали map<std::string, std::string>, но вы map сделаны из элементов другого типа. Эти ошибки имеют смысл сейчас?

Обновление: Поскольку вы просите прочитать и записать оба файла, вот полное решение:


#include <tuple>
#include <map>
#include <set>
#include <iostream>
#include <fstream>

void read_from_file(const std::string &fileName, std::map<std::tuple<int, int, int>, std::set<int>> &targetMap) {

    std::ifstream myStream(fileName);
    if (!myStream.is_open()) {
        std::cout << "Error opening file" << std::endl;
        return;
    }

    int a, b, c, set_size;
    while (myStream >> a >> b >> c >> set_size) {
        std::tuple<int, int, int> tuple(a, b, c);
        std::set<int> set;

        for (int i = 0; i < set_size; i++) {
            int val;
            myStream >> val;
            set.insert(val);
        }
        targetMap[tuple] = set;
    }
}

void write_to_file(const std::string &fileName, const std::map<std::tuple<int, int, int>, std::set<int>> &sourceMap) {
    std::ofstream myFile(fileName);
    if (!myFile.is_open()) {
        std::cout << "Failed to open file" << std::endl;
        return;
    }

    for (const auto &it:sourceMap) {
        myFile << std::get<0>(it.first) << " " << std::get<1>(it.first) << " " << std::get<2>(it.first) << " ";
        myFile << it.second.size()
               << " "; // i'll be easier to set values read from file.. otherwise we need to use stringstream
        for (const auto &it1: it.second) {
            myFile << it1 << " ";
        }
        myFile << std::endl;
    }
    myFile.flush();
}


int main() {
    // Create dict here
    std::map<std::tuple<int, int, int>, std::set<int>> sourceMap;
    for (int i = 0; i < 10; i++) {
        std::tuple<int, int, int> tup_key = {i, i, i};
        std::set<int> set_val = {i};
        sourceMap[tup_key] = set_val;
    }

    write_to_file("file_1.txt", sourceMap);

    // now let's read it..
    sourceMap.clear();
    read_from_file("file_1.txt", sourceMap);

    for (const auto &it:sourceMap) {
        std::cout << std::get<0>(it.first) << " " << std::get<1>(it.first) << " " << std::get<2>(it.first) << " ";
        std::cout << it.second.size() << " ";
        // it'll be easier to set values read from file.. otherwise we need to use stringstream
        for (const auto &it1: it.second) {
            std::cout << it1 << " ";
        }
        std::cout << std::endl;
    }

    return 0;
}

Вы можете очень легко записать в файл, используя ofstream и получить доступ к правильным членам:

#include <tuple>
#include <map>
#include <set>
#include <iostream>
#include <fstream>

int main() {
    // Create dict here
    std::map<std::tuple<int, int, int>, std::set<int>> hash_DICT;
    for (int i = 0; i < 10; i++) {
        std::tuple<int, int, int> tup_key = {i, i, i};
        std::set<int> set_val = {i};
        hash_DICT[tup_key] = set_val;
    }

    std::ofstream myfile;
    myfile.open("output.txt");

    if (!myfile.is_open()) {
        std::cout << "Failed to open file" << std::endl;
        return 0;
    }

    for (const auto &it:hash_DICT) {
        myfile << std::get<0>(it.first) << " " << std::get<1>(it.first) << " " << std::get<2>(it.first) << " --> ";
        for (const auto &it1: it.second) {
            myfile << it1 << " ";
        }
        myfile << std::endl;
    }

    myfile.flush();

    return 0;
}
...