First of all, I'd like to say that I'm not quite sure as to what exactly you're trying to achieve here. I'll just go with what I think is right -- that you are attempting to create an effect similar to that of standard Unix shell piping within a C++ program. That is, you are trying to let different "filters" process the input (which can be the output of an earlier filter) one at a time until you reach the last filter (which would be equivalent to the command on the right side of the last piping character, |). I hacked together a quick example that shows how this can be accomplished by having a base class "Filter" which provides a pure virtual "process" function, and a function to connect the filter to another filter. When a filter is connected to another, its output will be sent as input to that filter, and that filter will pass its output on, etc, until the end of the line is reached.
In the example I provide here, I use a filter chain containing two filters: one that converts all alphabetic characters to upper case, and one that strips all digits from the input string. In my main() function, I feed the first filter with a testing string, "Hello World 1234!". This string is first run through the upper case converter filter, which outputs "HELLO WORLD 1234!". Then, it is fed through the digit remover filter, which outputs "HELLO WORLD !". We retrieve the output from the digit remover filter, as it is the last, and print it the regular way.
Note that this is by no means the best possible way of accomplishing this. Far more robust and clean solutions could be created, but it works rather well for a hack.
I hope I got your question right, and that you will find the attached code useful. Good luck!
Code: Select all
#include <iostream>
#include <cctype>
class Filter
{
public:
Filter()
{
m_next = NULL;
m_output = "";
}
virtual ~Filter()
{
}
void connect(Filter *next)
{
m_next = next;
}
virtual void process(const std::string& input) = 0;
void next()
{
if(m_next)
{
m_next->process(m_output);
}
}
const std::string& getOutput() const
{
return m_output;
}
protected:
std::string m_output;
private:
Filter *m_next;
};
class UppercaseConverter : public Filter
{
public:
UppercaseConverter() : Filter()
{
}
virtual ~UppercaseConverter()
{
}
virtual void process(const std::string& input)
{
const size_t len = input.size();
// Clear old output!
m_output.clear();
for(size_t i = 0; i < len; i++)
{
m_output += toupper(input[i]);
}
// Make sure we pass it on.
this->next();
}
};
class DigitRemover : public Filter
{
public:
DigitRemover() : Filter()
{
}
virtual ~DigitRemover()
{
}
virtual void process(const std::string& input)
{
const size_t len = input.size();
// Clear previous outputs.
m_output.clear();
for(size_t i = 0; i < len; i++)
{
// Include all but digits.
if(!isdigit(input[i]))
{
m_output += input[i];
}
}
// Invoke next filter, if any.
this->next();
}
};
int main()
{
DigitRemover dgr;
UppercaseConverter ucc;
ucc.connect(&dgr);
ucc.process("Hello World 1234!");
std::cout << "Result: " << dgr.getOutput() << std::endl;
return 0;
}