I am trying to write some tool for MSDOS environment but it doesn't work as expected.
I want to get the tool to read from some commandline pipe, like
C:\> type a.txt|testpipe
where testpipe.exe is the compiled program.
The problem: After going through the piped contents, it does not stop at the CIN prompt marked in red. It just skips the reading but outputs all the prompts. Do I need to do something to fix the input after the pipe so it reads from the terminal?

#include<iostream>
#include<string>
  using namespace std;

int main(int argc,char*argv[])
{
char a[100];
string b;
while(cin.getline(a,100))
{
// TYPING OUT THE PIPED CONTENTS TWICE
b=string(a);
cout<<a<<"\n";
cout<<b.c_str()<<"\n";
}
// SHOWING THE STATES B4 CLEARING ERRORS
cout<<"RDstate function: "<<cin.rdstate()<<endl;
cout<<"   EOF  function: "<<cin.eof()<<endl;
cout<<"  FAIL  function: "<<cin.fail()<<endl;
cout<<"   BAD  function: "<<cin.bad()<<endl;
cout<<"  GOOD  function: "<<cin.good()<<endl;
cin.clear();
cin.ignore(0,-1);

// SHOWING THE STATES AFTER CLEARING ERRORS
cout<<"RDstate function: "<<cin.rdstate()<<endl;
cout<<"   EOF  function: "<<cin.eof()<<endl;
cout<<"  FAIL  function: "<<cin.fail()<<endl;
cout<<"   BAD  function: "<<cin.bad()<<endl;
cout<<"  GOOD  function: "<<cin.good()<<endl;

// READ FROM TERMINAL INPUT
cout<<endl<<"Please enter something to test terminal input:"<<endl;
cout<<"RDstate function: "<<cin.rdstate()<<endl;
cout<<"   EOF  function: "<<cin.eof()<<endl;
cout<<"  FAIL  function: "<<cin.fail()<<endl;
cout<<"   BAD  function: "<<cin.bad()<<endl;
cout<<"  GOOD  function: "<<cin.good()<<endl;
cin.getline(a,100);
b=a;
cout<<"Input:\t"<<a<<endl;
cout<<"Input(string):\t"<<b.c_str();
return 0;
}

Recommended Answers

All 4 Replies

So what is wrong with my question? I dont see any replies yet.
Can anyone reproduce the problem with the same results?
Is the redirection of output in MSDOS hard to understand?
Is the topic too in-depth? Comments are appreciated if you
can't come up with a solution.

You're redirecting stdin to the pipe, it won't read from the keyboard anymore. If you want to manage both piped data and keyboard data, a better approach is opening the pipe within your program rather than redirecting input from the command line. For example:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>

using namespace std;

int main(int argc, char *argv[])
{
    if (argc > 1) {
        FILE *pipe = _popen(argv[1], "r");
        char buf[BUFSIZ];
        
        while (fgets(buf, sizeof buf, pipe) != 0) {
            buf[strcspn(buf, "\n")] = '\0';
            cout << buf << '\n';
        }
        
        _pclose(pipe);
    }
    
    string input;
        
    cout << "Enter a string: ";
    
    if (getline(cin, input))
        cout << "Output: " << input << '\n';
}

Then call it as C:\>testpipe "type a.txt" .

thank you for your help, Narue.
I ran the code you provided but it seems to call a separate command window to do the job. The process flow of the code is

command window -> the tool -> new command window

but this is not exactly what I want. Also, for the nature of project I cannot stop the use of pipes in commandline. However, I am thankful to Narue for your response and that I learned _popen and _pclose functions from it.

Synopsis of my project: I want to develop my own cross-platform command tools, for both DOS and windows. As you may notice, the existing command tools for windows are not very useful, DOS (I still keep a computer for old DOS games ^_^) tools are even less. Thus I want to develop some on my own. Most command tools deal a lot with pipes, and I have the need to preserve the pipes.

but this is not exactly what I want

Examples meant to show a concept usually aren't.

Also, for the nature of project I cannot stop the use of pipes in commandline.

This doesn't change the fact that stdin is redirected. If you can't change that, you'll need to redirect it back within the code (not easy), open another input stream to simulate stdin, or use raw input methods. In your case, you'd have the most control with raw input methods, but it's also the lowest level, so you pay for that control with having to deal with things that the shell usually manages.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.