c ++ Как я могу эффективно форматировать std :: string с коллекцией? - PullRequest
0 голосов
/ 06 мая 2020

У меня есть программа со строкой (которую необходимо отформатировать), которая принимает набор элементов из внешнего источника.
Строка должна быть отформатирована с использованием элементов коллекции, которыми являются std :: string.
Я не могу форматировать строку вручную, например:

// Just examples
sprintf(test, "%s this is my %s. This is a number: %d.", var[0], var[1], etc..);        // i can't do this
fmt::printf("%s this is my %s. This is a number: %d.", var[0], var[1], etc..);          // i can't do this (i also have fmt library)

Это потому, что количество элементов в коллекции является переменным.
Я бы хотел отформатировать строка как можно эффективнее.

Это код:

std::string test = "%s this is my %s. This is a number: %d.";
std::vector<std::string> vec;

vec.push_back("Hello");
vec.push_back("string");
vec.push_back("5");


// String Formatting
std::size_t found;
for (auto i : vec)
{
    found = test.find("%");
    if (found != std::string::npos)
    {
        test.erase(found, 2);
        test.insert(found, i);
    }
}

std::cout << test;

Примечание1: я использовал std :: vector для управления элементами коллекции, но я мог бы использовать любую другую структуру .

Вот почему я не поместил определения в код.

Кроме того, написанный мной код не работает, если у меня есть строка с процентом, например:

std::string test = "%s this is a percentage: %d%%. This is a number: %d.";
// Output = "Hello this is a percentage: string5. This is a number: %d."

В заключение: каков наиболее эффективный способ форматирования строки с несколькими элементами?
Даже без использования вектора, но с использованием другой структуры. Или с помощью fmt или boost? (возможно, повышение снижает эффективность)
Моя среда разработки - Visual Studio 2019.

1 Ответ

0 голосов
/ 06 мая 2020

Вы можете сделать это, используя недавно добавленный {fmt} dynamic_format_arg_store (https://github.com/fmtlib/fmt/releases/tag/6.2.0):

#include <fmt/format.h>

int main() {
  fmt::dynamic_format_arg_store<fmt::format_context> args;
  args.push_back("Hello");
  args.push_back("string");
  args.push_back("5");
  fmt::vprint("{} this is my {}. This is a number: {}.", args);
}

Это напечатает (https://godbolt.org/z/jUbbUi):

Hello this is my string. This is a number: 5.

Обратите внимание, что {fmt} использует {} вместо % для полей замены.

...