I am trying to write a set of simple C ++ programs that follow the basic Unix philosophy:
- Do each program well.
- Expect the output of each program, which will be the entrance to another, yet unknown, program.
I had a problem with trying to get the output of one of them to input the other, and getting the result of one of them is the contribution of a separate instance. Very shortly, I have an add program that takes arguments and spits out the summation. I want to be able to connect the output to another instance to add .
./add 1 2 | ./add 3 4
That should give 10 , but currently gives 7 .
I ran into two problems:
- cin is waiting for user input from the console. I do not want this and could not find a simple example showing the use of a standard input stream without a user request in the console. If anyone knows an example, please let me know.
- I cannot figure out how to use standard input with piping support. Currently, it does not seem to be working. If I issue the command ./add 1 2 | ./add 3 4 , this results in 7.
The corresponding code is given below:
add.cpp snippet
// ... COMMAND LINE PROCESSING ... std::vector<double> numbers = multi.getValue(); // using TCLAP for command line parsing if (numbers.size() > 0) { double sum = numbers[0]; double arg; for (int i=1; i < numbers.size(); i++) { arg = numbers[i]; sum += arg; } std::cout << sum << std::endl; } else { double input; // right now this is test code while I try and get standard input streaming working as expected while (std::cin) { std::cin >> input; std::cout << input << std::endl; } } // ... MORE IRRELEVANT CODE ...
So, I guess my question (s) is: does anyone see what's wrong with this code to support standard piping input? Are there any well-known (or hidden) resources that clearly explain how to implement an example application that supports the basic Unix philosophy ?
@ Chris Lutz I changed the code to the one below. The problem is when cin is still waiting for user input to the console and does not just take from standard input transferred from the channel. Have I really missed something trivial for this? I have not tried to answer Greg Huglill yet, but I do not understand how this will help, since the problem is still related to cin.
// ... COMMAND LINE PROCESSING ... std::vector<double> numbers = multi.getValue(); // using TCLAP for command line parsing double sum = numbers[0]; double arg; for (int i=1; i < numbers.size(); i++) { arg = numbers[i]; sum += arg; } // right now this is test code while I try and get standard input streaming working as expected while (std::cin) { std::cin >> arg; std::cout << arg << std::endl; } std::cout << sum << std::endl; // ... MORE IRRELEVANT CODE ...
EDIT:. Almost there, it allows output to be output, however it seems to duplicate the duplicate. I release ./add 1 2 | ./add 3 4 and get 13 . With some additional cout statements in the while loop, I see two 3 values ββcoming from cin when I have only one cout statement. Why am I getting a duplicate?
// ... COMMAND LINE PROCESSING ... std::vector<double> numbers = multi.getValue(); // using TCLAP for command line parsing double sum = numbers[0]; double arg; for (int i=1; i < numbers.size(); i++) { arg = numbers[i]; sum += arg; } if (!isatty(fileno(stdin))) { while (std::cin) { std::cin >> arg; // this may require the use of std::strtod(), but to simplify the example I'm keeping it as this. sum += arg; } } std::cout << sum << std::endl; // ... MORE IRRELEVANT CODE ...