Control stdin and stdout of second program (pipes/piping?) - c++

I've been wondering how to go about running a program within another program where the the main process can output into the stdin of the secondary process as well as have that second process output to the input to the primary one.
The closest I have come to finding a term for this idea is pipes and forks but I don't quite get the examples i've seen. I've only seen ones where the same program is using pipes to launch itself again. Additionally all of these examples assume that that the programmer is writing/has access to both program's source code.
I would like to be able to interface in this way with programs that are already compiled. Here's an example of what I would like to be able to do:
This is the "compiled" program-
#include <iostream>;
using namespace std;
int main(){
int answer = 42;
int guess = 0;
do{
cout << "Guess a number..." << endl;
cin >> guess;
if(guess<answer)
cout << "Guess Higher!" << endl;
else if(guess>answer)
cout << "Guess Lower!" << endl;
}while(answer!=guess);
cout << "You win!";
return 0;
}
This is the "parent" program-
#include <iostream>;
using namespace std;
int main(){
//Code executing and connecting the other program
//while cin/cout would be nice for keeping it clean, other methods of doing this are fine
//I used cin/cout as placeholders to try and make what I am asking clearer
String out;
cin >> out;//Load initial prompt
int high=100, low=0;
do{
cout << (high+mid)/2 << endl;
cin >> out;//Load response
if(out.compare("Guess Higher!"))
low = (high+low)/2;
else
high = (high+low)/2;
}while(out.compare("You win!")!=0);
return 0;
}
The idea here is that my "parent" program could play this game for me. It would make a guess, view the response, use some logic to decide what to do next, guess, repeat until it wins. This particular example is pretty useless but the same general idea of controlling one program with another has a lot of uses. This is just a hypothetical demo of would I would like to be able to do.
Thanks to anyone kind enough to take time out of their day to help.

Related

std::cin is not accepting input

I am trying to get the first program working from "Accelerated C++".
I was having trouble getting the program to stay open without shutting down, so I decided to put a int i = 0; and cin >> i; after main() returns. Unfortuantely, it doesn't seem to take any input, no matter where I put that cin statement.
If it helps, it is using an istream reference to accept cin input. I can't figure out how to enter code on this site.
For most of my adult life, I used system("PAUSE") without any problems to keep the program window open. It's not good for real-time systems, of course, but it's simple and powerful because you're actually running a console command and it can be used to make console scripts.
#include <iostream>
#include <cstdlib>
using namespace std;
inline void Pause () { cout << "\n"; system ("PAUSE); }
int main () { Pause (); }
This solution is not 100% portable, but it will work on PCs. A more portable solution is:
#include <conio.h>
#include <cstdio>
void Pause() {
cout << "\nPress any key to continue...";
while (_getch() < 0)
;
}
cin is good for doing simple things, but what I do is wrap the std library in C functions and use those because it can dramatically improve compile times to hide the std library headers in the implementation files.
The prefered method in C++ is std::getline() using std::string, though many teachers won't let you use that.
With cin, you also have to clear input errors and use ignore() to throw away a specific number of chars.
#include <string>
string foo;
cout << "Why do they always use foo? ";
getline (cin, foo);
cout << "You just entered" << foo;
int bar;
cout << "\nThe answer is because programmers like to go to the bar."
"\nHow many times have you seen foo bar in an example? ";
while (!(cin >> bar)) {
cout << "\nPlease enter a valid number: ";
cin.clear ();
cin.ignore (10000, '\n');
}
My many years of experience have taught me to put the \n char at the beginning of output lines as opposed to the end of them.

Nesting int main() inside int main()

I am trying to make the simplest of all games, but with a loop function.
I'm given the error "a function-definition is not allowed here before '{', as well as a whole list of [Error] expected '}' at end of input.
Am I not allowed to nest int main() within another? Is that my issue at all? How do I accomplish this code without the nesting?
My knowledge and experience extend no more than a few chapters in two books.
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
char again = 'y';
while (again == 'y')
int main()
{
srand(static_cast<unsigned int>(time (0)));
int secret = rand() % 100 +1;
int tries = 0;
int guess;
cout << "\tGuess the random number\n\n";
do
{
cout << "Enter a guess: ";
cin >> guess;
++ tries;
if (guess > secret)
{
cout << "Too High!\n\n:";
}
else if (guess < secret)
{
cout << "Too Low!\n\n";
}
else
{
cout << "\nThat's It! You go it in " << tries << " guesses!\n";
}
} while (guess != secret);
}
cout << "\n\tWould you like to play again? (y/n): ";
char again;
cin >> again;
}
Your issue is nesting a main function inside of the existing main function. (This is not allowed.) In general, (With the exception of some stuff you can do with structs/lambdas which approximate that kind of functionality) you shouldn't nest functions inside of each-other. If you merely remove the function declaration, then your code should work fine:
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
char again = 'y';
while (again == 'y')
{
srand(static_cast<unsigned int>(time (0)));
int secret = rand() % 100 +1;
int tries = 0;
int guess;
cout << "\tGuess the random number\n\n";
do
{
cout << "Enter a guess: ";
cin >> guess;
++ tries;
if (guess > secret)
{
cout << "Too High!\n\n:";
}
else if (guess < secret)
{
cout << "Too Low!\n\n";
}
else
{
cout << "\nThat's It! You go it in " << tries << " guesses!\n";
}
} while (guess != secret);
cout << "\n\tWould you like to play again? (y/n): ";
cin >> again;
}
}
As far as I know, you cannot nest int main() inside of int main() for a number of reasons. In general, you can't define one function inside of another (defining "locally"). However, even if you can, your desire to do so should be a massive red flag that your design is off.
NOTE: As Nathan Oliver pointed out in the comments, you can forward-declare a function "locally" (within another function), but the actual implementation must be outside. Even doing this, you should usually second-guess your design at this point.
You need to be asking yourself what you're trying to do.
Are you wanting to group code together under a function to call repeatedly? Then create a separate function (with a different name) outside of main().
Are you wanting to repeat code? If so, you need a loop or a recursive function structure.
Are you wanting to split up some behavior into several functions, but hide all but one function involved? If so, look into classes (not necessarily objects - you can also have static classes.)
Those are just three of many possibilities, and deciding exactly what you want to do and how you want to do it is your responsibility alone to decide, as a programmer.
Brief recap: as far as C++ (and C) are concerned, if you're trying to declare any function inside any other function, you are doing something seriously wrong in design.
On a more technical note, you should also understand precisely what int main() is. It is a special function that is the entry point for your program. No C or C++ program can run without an int main().
You have to have a single instance of this function in main.cpp in order for your program to work. If you have more than one int main(), the computer cannot likely will not be able to find the entry point.
Besides that, having more than one function called main() anywhere in your code is a great way to confuse yourself and others.
In short, you should only have one int main() per program, no exceptions.

Why is this code exiting at this point?

I'm new to C++. I stumbled upon one tutorial problem, and I thought I'd use the few things I have learnt to solve it. I have written the code to an extent but the code exits at a point, and I really can't figure out why. I do not want to go into details about the tutorial question because I actually wish to continue with it based on how I understood it from the start, and I know prospective answerers might want to change that. The code is explanatory, I have just written few lines.
Here comes the code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
double average_each_student() {
cout << "\n>Enter your scores seperated by spaces and terminated with a period\n"
<< ">Note: scores after total number of six will be truncated.\n"
<< endl;
double sum = 0, average = 0;
int user_input, counter = 0;
const double no_of_exams = 6;
while(cin >> user_input) {
++counter;
if(counter < 5) sum += 0.15 * user_input;
else if(counter > 4 && counter < 7) sum += 0.20 * user_input;
}
return sum / no_of_exams;
}
int reg_number() {
cout << "Enter your registration number: " << endl;
int reg_numb;
cin >> reg_numb;
return reg_numb;
}
int main() {
vector<int> reg_num_list;
vector<double> student_average;
reg_num_list.push_back(reg_number());
student_average.push_back(average_each_student());
string answer;
cout << "\n\nIs that all??" << endl;
//everything ends at this point.
//process returns 0
cin >> answer;
cout << answer;
}
The code exits at cout << "\n\nIs that all??" << endl;. The rest part after that is not what I intend doing, but I'm just using that part to understand what's happening around there.
PS: I know there are other ways to improve the whole thing, but I'm writing the code based on my present knowledge and I wish to maintain the idea I'm currently implementing. I would appreciate if that doesn't change for now. I only need to know what I'm not doing right that is making the code end at that point.
The loop inside average_each_student() runs until further input for data fails and std::cin gets into failure state (i.e., it gets std::ios_base::failbit set).
As a result, input in main() immediately fails and the output of what was input just prints the unchanged string. That is, your perception of the program existing prior to the input is actually wrong: it just doesn't wait for input on a stream in fail state. Since your output doesn't add anything recognizable the output appears to do nothing although it actually prints an empty string. You can easily verify this claim by adding something, e.g.
std::cout << "read '" << answer << "'\n";
Whether it is possible to recover from the fail state on the input stream depends on how it failed. If you enter number until you indicate stream termination (using Ctrl-D or Ctrl-Z on the terminal depending on what kind of system you are using), there isn't any way to recover. If you terminate the input entering a non-number, you can use
std::cin.clear();
To clear the stream's failure stated. You might want to ignore entered characters using
std::cin.ignore(); // ignore the next character
or
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// ignore everything up to the end of the line
use cin.clear(); before cin >> answer; That will fix the problem. But you are not controlling the input. it just runs out to cin..

Why does a cout statement at the beginning of my program not output anything?

So I'm working on some code for a class. Yes I know the input validation I'm trying to work out is inefficient and the program is unfinished. I don't need the rest of it to work. Here's the code.
/*Write a program that allows the user to enter a payroll code.
The program should search for the payroll code in the file and then display the appropriate salary.
If the payroll code is not in the file, the program should display an appropriate message.
Use a sentinel value to end the program.*/
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main(){
int code;
ifstream PayrollFile;
int FCode;
int Salary;
char Trash;
string line;
string lineTwo;
int NumOfCodes=0;
int Subscript=0;
cout << "everything is starting";
PayrollFile.open("/Users/fnord/Desktop/Payroll.txt");
do{
lineTwo=line;
PayrollFile >> line;
NumOfCodes++;
}
while (line!=lineTwo);
PayrollFile.close();
PayrollFile.open("/Users/fnord/Desktop/Payroll.txt");
int ListOfPayrollCodes[NumOfCodes-1];
while (Subscript<NumOfCodes){
while (PayrollFile >> FCode >> Trash >> Salary) {
cout << FCode;
ListOfPayrollCodes[Subscript]=FCode;
Subscript++;
}
}
PayrollFile.close();
PayrollFile.open("/Users/fnord/Desktop/Payroll.txt");
cout << "please enter the payroll code";
cin >> code;
while (PayrollFile >> FCode >> Trash >> Salary) {
if (code==FCode) {
cout << "The salary is " << Salary << endl;
}
}
PayrollFile.close();
}
The thing I'm confused about is the fact that the compiler never seems to reach this line:
cout << "everything is starting";
As far as I can tell, there is nothing before this line that should stop the program from outputting "everything is starting" but "everything is starting" never shows up in the output.
The code builds and begins running but never stops and fails to output anything. My teacher couldn't figure this out either.
I'm running OSX10.9 and using XCode for my compiler. I've tried other compilers with the same results.
Thanks!
In these loops:
while (Subscript<NumOfCodes){
while (PayrollFile >> FCode >> Trash >> Salary) {
cout << FCode;
ListOfPayrollCodes[Subscript]=FCode;
Subscript++;
}
}
If extraction fails, PayrollFile starts converting to false, and there's no longer any way for Subscript to increase. So the outer loop never terminates.
Instead use:
while ((Subscript<NumOfCodes) && (PayrollFile >> FCode >> Trash >> Salary)) {
cout << FCode;
ListOfPayrollCodes[Subscript]=FCode;
Subscript++;
}
For your printf-debugging needs, when using cout, also use std::flush or std::endl. Otherwise the output will be buffered, and not help you learn where your program got stuck. (For actually writing out large quantities of data, you'll want to avoid flushing any more than necessary, because it kills performance.)
Use breakpoints. when you started to debug check if they are still red or turned white. if turned white you can see a note there about the situation. if its red and you cant reach it means its never getting there.
cout is a buffered stream; to force the output you should
using endl manipulator;
usinf flush() method
int ListOfPayrollCodes[NumOfCodes-1]; - // This line should not compile.You're using a variable to declare the size of an array . This is supposed to be a constant.
I'm not sure how you compile this code. Please fix a constant and see, how it sounds. I hardcoded it and commented the Numcodes increment line and I could print it.
Update: Ok, Looks like you're saying the compiler does not reach this line. That means, the code does not compile. The reason is above.
I understand that you want an array of size ListOfPayrollCodes. Use dynamic allocation as opposed to static allocation, it will work fine.

Is there such thing as Two-way Piping? I want input and output to be interactive between two simple programs

I want to write a program to solve a simple guessing game. I'm learning about command line piping and redirects, and so I was wondering if this is even possible.
Basically I want the output of one to be the input of the other, and then the output of that to be the input of the other.
This is all just for fun so I can learn, I know I can change the source code of the guessing game and include the solving algorithm, but just for fun let's assume I don't have the source code.
Is this even possible? Here's my code:
//GuessingGame.cc
#include <cstdlib>
#include <iostream>
using namespace std;
int main() {
srand(time(NULL));
int number = rand()%100;
int guess = -1;
int trycount = 0;
while(guess != number && trycount < 8) {
cout << "Please enter a guess: ";
cin >> guess;
if(guess < number)
cout << "Too low" << endl;
else if(guess > number)
cout << "Too high" << endl;
trycount++;
}
if(guess == number)
cout << "You guessed the number!";
else
cout << "Sorry, the number was: " << number;
return 0;
}
Solver.cc
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char* argv[]) {
string prompt;
int high = 100;
int low = 0;
int guess = 50;
getline(cin,prompt);
if(prompt == "Please enter a guess: ")
cout << guess;
while(true) {
getline(cin,prompt);
if(prompt == "Too low")
low = guess;
else if(prompt == "Too high")
high = guess;
else if(prompt == "You guessed the number!")
return 0;
guess = (low+high)/2;
cout << guess;
}
}
I hope you understand what I'm doing, and I don't care so much about the program, it's just an example. The main question is if you can interact with two different programs, using redirects and piping and such. Thanks
A pipe is by definition a one-way communication device. However it can be solved by using two pipes, one in each direction. The problem is that it can't be done easily through a shell, you have to make a program to set up the pipes, creates the processes for your programs and then executes them with the pipes set up as the correct input/output channels.
The only way I can think about how to make this possible through a shell, is to use the mkfifo command to create two pipes. Start one program in the background with the input and output redirected from/to the correct pipes, and then do the same with the other program but use the other pipe as input and output.
Pipes are one-way. If you open a pipe in your programming language of choice, you have to handle creating two pipes yourself.
The traditional abstraction for two-way I/O provided by the Korn family of shells is the coprocess. The syntax for shells with "ksh" in their names is mostly portable.
ksh93 / mksh / other pdkshes:
{ cmd1...; } |& cmd2 <&p >&p
Bash and Zsh, though sharing many of the same features, have different, incompatible syntaxes. Bash for example adds an extra keyword and assigns FDs to an array.
coproc { cmd1; }; cmd2 <&"${COPROC[0]}" >&"${COPROC[1]}"
The main alternatives to coprocesses are process substitutions, ordinary pipelines, and named pipes, but they are not bidirectional in themselves.