Question

Is there a way to do the following, but passing only bounds to printf?

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);
Was it helpful?

Solution 2

I assume the reason why you want to optimize this is that you need to print a lot of bounds in your program and it is tiresome to write like this, it is error prone etc.


In C, you could use a macro like this:

#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));

In C++, you are more expected to use std::cout or similar stream. Then you could write a custom object to do this for you:

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;
    }
};

Then you would use it like this:

std::cout << "Some other text: " << PrintBounds(bounds) << " ...\n";

OTHER TIPS

You can write your own 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;
}

I wrote this in C, I think it can be converted to C++ easily (I don't know C++).

  • I'm posting a C++11 version of a one line printing algorithm. I coded a functor (i.e., PairPrintFunctor) that in association with for_each can print containers with even number of elements. If the container contains odd number of elements the last is ignored. You can also set your own delimiters.

  • Note However, that you can't avoid the iteration. In the background there's an iterative procedure due to 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

Its not possible. See:

http://en.cppreference.com/w/c/io/fprintf

Alternatively, break out the code into its own function.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top