I have a C++ program that outputs prompts and takes user input via the standard input stream cin.
I want to get a full transcript including both the program's output and the input in a file.
I know I can redirect input/output with command-line redirection (i.e. ./program < in.txt > out.txt), but this will only fill out.txt with the program's output in response to the input from in.txt.
I want to have a transcript that shows both the input and output. That is, let's say my program outputs a prompt "\nEnter a number: ", takes a user inputted number and outputs its double, "\nTwice your number is: ", and keeps doing this until the user enters a 0.
Let's say I have in.txt containing:
1
3 0
Then I want to have a transcript of input/output:
Enter a number: 1
Twice your number is: 2 Enter a number: 3 Twice your number is: 6 Enter a number:开发者_StackOverflow社区 0 Twice your number is: 0
Sorry if I didn't explain this very well... I didn't really know how to word it.
Is there a way to do this simply, or do I just have to enter the input by hand... and do some save of the terminal...
script
doesn't cover your exact use case. You'd like to see the input and output to your program exactly as a user would see it, but without having to do it yourself.
I found Expect, which seems to be exactly what we're looking for. I don't know Tcl, but there's a Python port, pexpect
. You'll need to install pexpect:
wget http://pexpect.sourceforge.net/pexpect-2.3.tar.gz
tar xzf pexpect-2.3.tar.gz
cd pexpect-2.3
sudo python ./setup.py install
Then copy this code into an executable file:
#! /usr/bin/env python
import sys, pexpect
executable = sys.argv[1]
infile = sys.argv[2]
proc = pexpect.spawn(executable)
file = open(infile)
for line in file:
proc.send(line)
proc.sendeof()
proc.expect(pexpect.EOF)
print proc.before,
And then you can run it like so:
transcript ./executablefile fileforinput
My sample run gave me this output:
Enter a number: 1
Twice your number is: 2
Enter a number: 2
Twice your number is: 4
Enter a number: 3
Twice your number is: 6
Enter a number: 0
Twice your number is: 0
Assuming I read your question right, that should be the exact answer you're looking for. And it works on any program without any modification at all.
Hope that helps!
-Jake
The UNIX script
command will do it.
Interesting question. Something which should be cross platform is like the example below (I have tested on Windows and *nix but do not have a mac to test on unfortunately). Basically, you will read the initial file and extract its data (in the case of the example, it assumes that the file is formatted exactly as you have mentioned above) and store that data somewhere. Then, write the data back to the file from which you read it.
/**
* File Input/Output
*
* Input file is also output file
*
* 12/13/10
*/
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
// Get data and store it
ifstream in("output.txt");
// Simple error checking
if(!in.is_open())
{
cout<< "There was an error opening output.txt!" << endl;
return 0;
}
cout<< "Reading file..." << endl << endl;
// Strings are quicker to implement
string tmp;
string data;
int tmpi = 0;
// Here is where we store the input - the stringstream allows us to handle
// multiple variable types and convert them. NOTE: there is no error checking here,
// so wrong types _WILL_ throw errors (format needs to be one number per line)
stringstream ss(stringstream::in|stringstream::out);
while(getline(in,tmp))
{
tmpi = 0; // Reset
ss.str(string());
ss << tmp;
ss >> tmpi;
tmpi *= 2;
// Reset it again so we can get the doubled value
ss.clear();
ss.str(string());
ss << tmpi;
data.append("Enter a number: "+tmp+"\r\n"+"Twice your number is: "+ss.str()+"\r\n");
}
in.close();
// Output handling
ofstream out("output.txt",ios::binary|ios::trunc); // Delete everything which was in the file?
// Simple error checking
if(!out.is_open())
{
cout<< "There was an error opening output.txt!" << endl;
return 0;
}
cout<< "Generating output..." << endl << endl;
// Write to the file
out.write(data.c_str(),data.size());
out.close();
cout<< "Done!"<< endl;
cin.get(); // Pause momentarily
return 0;
}
My original input file was:
12
2312349
324843
3249
0909
The output was:
Enter a number: 12
Twice your number is: 24
Enter a number: 2312349
Twice your number is: 4624698
Enter a number: 324843
Twice your number is: 649686
Enter a number: 3249
Twice your number is: 6498
Enter a number: 0909
Twice your number is: 1818
Hope this helps!
Good luck!
Dennis M.
精彩评论