将数组作为参数传递给printf函数

3
有没有一种方式可以只传递boundsprintf,实现如下所示的操作?
double *bounds = getBounds();
printf("%f-%f, %f-%f, %f-%f",
    bounds[0], bounds[1],
    bounds[2], bounds[3],
    bounds[4], bounds[5] );

// what I'd like to write instead:
xxxprintf("%f-%f, %f-%f, %f-%f", bounds);

虽然没有可移植的标准方式,但一些printf实现允许新的转换格式,从而为您提供选项 - 例如http://www.gnu.org/software/libc/manual/html_node/Customizing-Printf.html。 - Tony Delroy
你是想要一种通用的打印数组/向量的方式,还是你想知道是否可以使用printf来实现这样的行为? - 101010
@40two 是前者。我认为传递六个参数很丑陋,希望能以其他方式解决这个问题(不用循环)。 - Anna
@Anna,你只能使用printf,你能用std::cout吗? - 101010
@40two 我不仅限于使用 printf。我认为我可以使用 std::cout。 - Anna
4个回答

4
您可以编写自己的xxxprintf()函数。
#include <stdio.h>

int arrayprintf_dbl(const char *fmt, const double *data) {
  int n = 0;
  const char *p = fmt;
  const double *x = data;
  while (*p) {
    if (*p == '%') {
      // complicate as needed ...
      p++;
      if (*p != 'f') return -1; // error
      n += printf("%f", *x++);
    } else {
      putchar(*p);
      n++;
    }
    p++;
  }
  return n;
}

int main(void) {
  double bonus[6] = {1, 2, 3, 4, 5, 6};
  arrayprintf_dbl("%f-%f, %f-%f, %f-%f\n", bonus);
  return 0;
}

我用C语言编写了这个程序,我认为它可以很容易地转换为C++(我不会C++)。


1
我猜你想要进行这个优化的原因是因为你的程序需要打印很多边界值,而像这样写很烦人,容易出错等。
在C语言中,您可以使用类似以下的宏:

#define BOUNDS_FORMAT "%f-%f, %f-%f, %f-%f"
#define BOUNDS_ARG(b) b[0], b[1], b[2], b[3], b[4], b[5]

Then write it just like so:

printf(BOUNDS_FORMAT, BOUNDS_ARG(bounds));
// ... some other code, then another call, with more text around this time:
printf("Output of pass #%d: " BOUNDS_FORMAT "\n", passNumber, BOUNDS_ARG(bounds));

在C++中,使用 std::cout 或类似的流更为常见。然后,您可以编写一个自定义对象来为您完成此操作:
class PrintBounds {
  protected:
    const double* m_bounds;

  public:
    PrintBounds(const double* bounds)
      : m_bounds(bounds)
    {
    }

    friend std::ostream& operator<<(std::ostream& os, const PrintBounds& self)
    {
        os << self.m_bounds[0] << "-" << self.m_bounds[1] << ", "
           << self.m_bounds[2] << "-" << self.m_bounds[3] << ", "
           << self.m_bounds[3] << "-" << self.m_bounds[5];
        return os;
    }
};

然后您可以像这样使用它:
std::cout << "Some other text: " << PrintBounds(bounds) << " ...\n";

1
  • 我正在发布一个C++11版本的一行打印算法。我编写了一个函数对象(即PairPrintFunctor),结合for_each可以打印具有偶数个元素的容器。如果容器包含奇数个元素,则最后一个元素将被忽略。您还可以设置自己的分隔符。

  • 请注意,您无法避免迭代。在后台,由于for_each存在着迭代过程。


#include <iostream>
#include <algorithm> 
#include <iterator>
#include <utility>
#include <memory>
#include <string>
#include <vector>

template<typename T>
class PairPrintFunctor
{
  std::size_t         _n;
  std::ostream       &_out;
  std::string         _delim;
  std::string         _sep;
  std::shared_ptr<T>   state;
public:
    explicit PairPrintFunctor(std::ostream &out, std::string delim = " ", std::string sep = " - ") : _n(0), _out(out), _delim(delim), _sep(sep) { }
    void operator()(T const &elem) 
    { 
        if(state == nullptr) {
          state.reset(new T(elem));
        } else {
          if (_n > 0) _out << _delim;
          _out << *state << _sep << elem;
          state.reset();
          state = nullptr;
          ++_n;
        }
    }
};

int main()
{
    int a[] {1, 2, 3, 4, 5, 6, 7, 8};
    std::for_each(std::begin(a), std::end(a), PairPrintFunctor<int>(std::cout, ", ", " --- "));
    std::cout << std::endl;
    std::vector<int> v{ 10, 20, 30, 40, 50, 60, 70, 80};
    std::for_each(std::begin(v), std::end(v), PairPrintFunctor<int>(std::cout, ", ", " --- "));
    std::cout << std::endl;
    return 0;
}

HTH


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接