Замена контейнера multimap на multiset

Есть код программы, только в нём используется контейнер multimap, и строки с длиной больше 11 и меньше 20. В файл должны быть записаны только строки длиной больше 10 и меньше 50 символов. Использовать контейнер multiset<std::string, Compare>. Входной файл существует на диске, выходной файл создается программой.

Задача данной программы - вывод строк где больше 10 символов и меньше 20. Сейчас программа работает с контейнером multimap. Нужно чтобы программа работала с контейнером multiset и выводила строки где больше 10 символов и меньше 50, и чтобы эти строки были упорядочены по длине.

#include <stdio.h>
#include <iostream>
#include <set>
#include <exception>
#include <stdexcept>

int main() {
    try {
        FILE* filein;
        FILE* fileout;
        /*char name[256];
        std::cout << "Enter the opening file's path:" << std::endl;
        std::cin >> name;*/
        /*char nameout[256];
        std::cout << "Enter the saving file's path:" << std::endl;
        std::cin >> nameout;*/
        char name[] = "in.txt";
        char nameout[] = "out.txt";
        if ((filein = fopen(name, "r")) == NULL)
            throw std::runtime_error("Can't open the file.");
        if ((fileout = fopen(nameout, "w")) == NULL) {
            fclose(filein);
            throw std::runtime_error("Can't create the file.");
        }
        std::multiset<int, int, std::greater <int>> mySet; //создание контейнера
        char str[1024];
        int len;
        int pos;
        std::string s;
        bool counter = 0;
        while (!feof(filein)) {
            if (fgets(str, 1024, filein)) {
                std::cout << str;
                s = str;
                len = s.length();
                pos = ftell(filein);
                if (len >= 11 && len <= 21)
                    counter++;
                mySet.insert(std::make_pair(len, pos - 1)); //заполнение контейнера
            }
        }
        if (counter == 0) {
            std::cout << '\n';
            fclose(filein);
            fclose(fileout);
            throw std::runtime_error("Required strings are missing.");
        }
        std::cout << std::endl;
        std::multiset<int, int>::iterator it; //объявление итератора
        std::cout << "result:" << std::endl;
        std::multiset<int, int>::iterator itlow, itup; //границы контейнера
        itlow = mySet.lower_bound(51);
        itup = mySet.upper_bound(11);               
        for (it = itlow; it != itup; ++it)
        {
            if ((it == mySet.end()) && (it->first >= 11) && (it->first <= 51)) //без доп условия последняя строка не выводится корректно
            {
                fseek(filein, it->second - it->first + 1, SEEK_SET);
                fgets(str, it->first + 1, filein);
            }
            else
            {
                fseek(filein, it->second - it->first, SEEK_SET);
                fgets(str, it->first, filein);
            }
            fputs(str, fileout);
            fputs("\n", fileout);
            //std::cout << it->first << "=" << it->second << std::endl;
            std::cout << str << std::endl;
        }
        fclose(filein);
        fclose(fileout);
    }
    catch (std::exception& exception)
    {   
        std::cerr << "Standard exception: " << exception.what() << std::endl;
    }
}

Ответы (1 шт):

Автор решения: Harry

Если - подчеркиваю - если ваш код работоспособен для multimap - в чем я не очень уверен, но не проверял (однако один лишь счетчик bool counter = 0; наводит на очень грустные размышления), то изменить его для multiset можно просто заменив ключ и значение на пару ключ/значение с компаратором, который сравнивает только ключи. Примерно так - определив компаратор наподобие

struct Cmp
{
    bool operator()(const std::pair<int,int>& a,
                    const std::pair<int,int>& b) const
    {
        return a.first < b.first;
    }
};

и изменив ваш "multiset<int,int>" на

std::multiset<std::pair<int,int>, Cmp> mySet;

Соответственно надо изменить и объявления итераторов - раз вас не устраивает auto, то

std::multiset<std::pair<int,int>, Cmp>::iterator itlow, itup;

а при поиске границ надо передавать пару, наподобие

itlow = mySet.lower_bound(std::make_pair(51,0));

Это - примерный план работ по замене. Еще раз повторюсь - я не проверял работоспособность вашего кода, но имею насчет этого большие сомнения...

→ Ссылка