
Question:
The following code is part of a larger translator program. The code below asks the user to type a line and than just writes it back. Is there a way that instead of writing a single line each time, I can just pass in a whole file etc 'translate.txt' in standard input and the program can write it back line by line and produces an error when the end of line is reached ?
#include <iostream>
#include <string.h>
#include<stdio.h>
#include<fstream>
using namespace std;
using namespace std;
void PL() {
char line[BUFSIZ];
while( cin.good() ) {
cout<<"Type line now"<<endl;
cout<<"\n";
cin.getline(line, sizeof(line));
cout<<"\n"<<endl;
string mystring = string(line);
// supposed to Parsing string into words and translate//
//but just reading back input for now//
cout<<"You typed:"<<mystring<<endl;
cout<<"\n"<<endl;
}
}
int main() {
PL();
}
Answer1:Do you expect a way to pass a file to your program?
executable < file
Answer2:<a href="http://ideone.com/XN91DP" rel="nofollow">This code works well for me</a>:
void PL() {
string line;
while(cin) {
cout<<"Type line now";
if(std::getline(cin,line)) {
// supposed to Parsing string into words and translate//
//but just reading back input for now//
cout<<"You typed:"<<line<<endl;
}
}
}
Note that the stdin
there is actually passed to the program from the shell as mentioned:
$ executable < file
<hr />If you want to pass arbitrary types of streams created from outside this function, you'll need something like
void PL(std::istream& is) {
string line;
while(is) {
cout<<"Type line now";
if(std::getline(is,line)) {
// supposed to Parsing string into words and translate//
//but just reading back input for now//
cout<<"You typed:"<<line<<endl;
}
}
}
int main() {
std::ifstream is("mytext.txt"); // hardcoded filename
PL(is);
return 0;
}
or alternatively
int main(int argc, char* argv[]) {
std::istream* input = &std::cin; // input is stdin by default
if(argc > 1) {
// A file name was give as argument,
// choose the file to read from
input = new std::ifstream(argv[1]);
}
PL(*input);
if(argc > 1) {
// Clean up the allocated input instance
delete input;
}
return 0;
}
<sub>There are certainly more elegant solutions</sub>
and calling from the command line:
$ executable mytext.txt
Answer3:Your shell will have a way to pass a file in over stdin. So for example, if you are on a bourne-compatible shell you can run
translate < translate.txt
(assuming your program is compiled to a binary named translate
). This is assuming you want to start the program interactively, i.e. from a shell.
If you want to automatically spawn this program from another program you wrote, it depends on your OS. On POSIX operating systems, for example, you will want to open
the file and dup2
the resulting file descriptor into STDIN_FILENO
after forking but before calling one of the exec
family functions.