3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

出力ストリームに区切り文字を自動で挿入する

Last updated at Posted at 2015-04-14

目的 :bulb:

CSV形式やTSV形式で出力したい時、区切り文字を毎回書くのはちょっと面倒。

for (size_t i = 1; i < 10; i++) {
  std::cout
    << "[csv] "
    << i
    << ", " << std::string(i, 'x')
    << ", " << std::boolalpha << (i % 2 == 0)
    << "\n";
}

次のように書けると気分が良い。

for (size_t i = 1; i < 10; i++) {
  make_auto_sep(std::cout, "[csv] ", ", ", "\n")
    << i
    << std::string(i, 'x')
    << std::boolalpha << (i % 2 == 0);
}

という類のものを何度も再発明していることに気付いたので、纏めたものをメモ。

コード :sparkles:

# include <iostream>
# include <string>

// 出力ストリームに区切り文字を自動で挿入するラッパクラス
template<class CharT, class Traits, class Sep, class End>
class AutoSep {
  std::basic_ostream<CharT, Traits>& os_;
  const Sep& sep_;
  const End& end_;
  bool is_first_ = true;

public:
  template<class Start>
  AutoSep(
    std::basic_ostream<CharT, Traits>& os,
    const Start& start,
    const Sep& sep,
    const End& end) : os_(os), sep_(sep), end_(end)
  {
    os_ << start;  
  }

  ~AutoSep()
  {
    os_ << end_;
  }

  // マニュピレータは区切り文字を入れない
  AutoSep& operator<<(std::ios_base& (*func)(std::ios_base&))
  {
    os_ << func;
    return *this;
  }

  // 二回目から区切り文字を入れる
  template<class T>
  AutoSep& operator<< (const T& v)
  {
    if (is_first_) {
      os_ << v;
      is_first_ = false;
    } else {
      os_ << sep_ << v;
    }

    return *this;
  }
};

// コンストラクタの型推論用
template<class CharT, class Traits, class Start, class Sep, class End>
AutoSep<CharT, Traits, Sep, End> make_auto_sep(
  std::basic_ostream<CharT, Traits>& os,
  const Start& start,
  const Sep& sep,
  const End& end)
{
  return AutoSep<CharT, Traits, Sep, End>(os, start, sep, end);
}

int main()
{
  for (size_t i = 1; i < 10; i++) {
    make_auto_sep(std::cout, "[csv] ", ", ", "\n")
      << i
      << std::string(i, 'x')
      << std::boolalpha << (i % 2 == 0);
  }

  return 0;
}

[Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ

出力 :white_flower:

[csv] 1, x, false
[csv] 2, xx, true
[csv] 3, xxx, false
[csv] 4, xxxx, true
[csv] 5, xxxxx, false
[csv] 6, xxxxxx, true
[csv] 7, xxxxxxx, false
[csv] 8, xxxxxxxx, true
[csv] 9, xxxxxxxxx, false
3
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?