Reputation: 2845
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);
Upvotes: 3
Views: 4636
Reputation: 42929
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
Upvotes: 1
Reputation: 13858
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";
Upvotes: 1
Reputation: 108988
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++).
Upvotes: 4
Reputation: 1641
Its not possible. See:
http://en.cppreference.com/w/c/io/fprintf
Alternatively, break out the code into its own function.
Upvotes: 0