格式化字符串

题目描述

通过编写适当的代码,使得表达式 "format_string"_fmt % arg1, arg2, .. 可以作为格式化字符串语法。其含义是:将 arg1arg2 转换到字符串并替换掉 format_string 里的 {} 占位符,当整个表达式用 std::cout 输出时,即可得到替换好的字符串。

比如 "{} + {} = {}"_fmt % 1, 2, 3std::cout 输出即可得到 1 + 2 = 3

关于输入

共两行。

第一行为一个不含空白字符或标点符号的字符串 s

第二行为两个空格分隔的整数 xy,取值范围在 ±107

关于输出

共三行。

第一行为 Good afternoon, s!,其中 s 是输入的字符串;

第二行为 x + y = z,其中 xy 是输入的整数,z=x+y

第三行为 He1l0, World!

注意事项

下述代码没有考虑更多细节,仅直接替换格式字符串中的 {}。此代码也没考虑 operator, 的误用问题;正确做法应类似 Boost.Assign,使用中间代理类。

参考答案

#include <iostream>
#include <sstream>
#include <string>

class Formatter {
    std::string buf;

    template <typename T>
    void insert(const T& v) {
        std::stringstream ss;
        ss << v;
        buf.replace(buf.find("{}"), 2, ss.str());
    }

public:
    Formatter(const std::string& fmt) : buf{fmt} {}

    template <typename T>
    Formatter& operator%(const T& v) {
        insert(v);
        return *this;
    }
    template <typename T>
    Formatter& operator,(const T& v) {
        insert(v);
        return *this;
    }

    friend std::ostream& operator<<(std::ostream& os, Formatter fmt) {
        return os << fmt.buf;
    }
};

Formatter operator""_fmt(const char* src, std::size_t size) {
    return Formatter(src);
}

int main() {
    std::string name;
    std::cin >> name;
    std::cout << ("Good afternoon, {}!"_fmt % name) << std::endl;
    int a, b;
    std::cin >> a >> b;
    std::cout << ("{} + {} = {}"_fmt % a, b, a + b) << std::endl;
    int i = 1;
    char c = 'c';
    std::string s = "World";
    std::cout << ("{}{}{}{},{}{}!"_fmt % "He", i, 'l', 0, ' ', s) << std::endl;
}