Send characters to console application - c++

I have simple console application that runs in terminal window reads and prints character:
int main(int argc, char **argv, char **envp)
{
while (true)
{
char c =getchar();
printf("%c \n",c);
}
}
Now I would like to make test application that could emulate character press in first application terminal.
Which way I should go? What API functions I should use for this purpose?

No need for special APIs or whatever. Since your sample application is only reading from standard input, you can just send stuff to there.
Before running the program in a terminal, check its connected terminal using tty command. Then send data to that tty that tty reports.
Alternatively, grab the PID of your running application and send data to /proc/$PID/fd/0 so you don't need to check for tty.

Just pipe the test data to your process:
echo "some test data" | ./myprogram
(Your example program in the question will read and print each letter from "some test data").
There are plenty of other variations on this. Read about the shell and shell pipelines.

Related

Read information that has been couted to the terminal

I am trying to figure out how to read information from the terminal or console, (I am using ubuntu)
I am not looking for cin, or readline.
I don't want user input, instead I want a program that will read text that is written in the terminal by cout, put_char etc... How can this information be accessed by a C++ program?
edit:
say I have a program that
int main(...)
{
cout << blahblahblah;
....
}
how can I read the information that was sent to the terminal?
int someFunc()
{
someIostream terminal;
string = terminal.readline();
}
Or as another example
suppose I have some user who has been running things on their terminal
and I want to see everything they typed in before running my program

Read line on stdin on Windows 10 IoT (Raspberry Pi 2)

I'm new to developing apps on Windows 10 IoT, so I made little test application just to test how to read input from stdin on a console app on a Raspberry Pi 2 running Windows 10.
Now I know that this is not the average use case, but my original app has the purpose to only serve as a demo.
My little code in C++ (for reasons I'm restricted to C++) so far is very simple:
#include "pch.h"
int main(int argc, char **argv) {
char buffer[1024];
std::cin.getline(buffer, 1024);
printf("%s \n", buffer);
}
The problem I face is, that the line
std::cin.getline(buffer, 1024);
seems to be omitted. All the program does is printing an empty line. So there isn't even time to type anything to stdin.
Maybe it's worth mentioning that I'm testing this via a powershell remote session so maybe this has anything to do with it.
My questions are now:
Is it even possible to read a line from stdin? (I guess so)
Am I doing it wright? (Certainly not)
What is the correct/clean way to do so? Where is my error?

Sending data to stdin of another process through linux terminal

I've been trying to send data to stdin of a running process. Here is what I do:
In a terminal I've started a c++ program that simply reads a string and prints it. Code excerpt:
while (true) {
cin >> s;
cout << "I've just read " << s << endl;
}
I get the PID of the running program
I go to /proc/PID/fd/
I execute echo text > 0
Result: text appears in the terminal where the program is run. Note, not I've just read text, but simply text.
What am I doing wrong and what should I do to get this thing to print 'I've just read text'?
When you're starting your C++ program you need to make sure its input comes from a pipe but not from a terminal. You may use cat | myapp to do that. Once it's running you may use PID of your application for echo text > /proc/PID/fd/0
It could be a matter of stdout not being properly flushed -- see "Unix Buffering". Or you could be in a different shell as some commentators have suggested.
Generally, it's more reliable to handle basic interprocess communication via FIFOs or NODs -- named pipes. (Or alternatively redirect stdout and/or stderr to a file and read from that with your c++ program.)
Here's some good resources on how to use those in both the terminal and c++.
"FIFO – Named pipes: mkfifo, mknod"
"Using Pipes in Linux Processes"
"Programming with FIFO: mkfifo(), mknod()"
FD 0 is the terminal the program is running from. When you write to FD 0, you are writing to the terminal the program is running from. FD 0 is not required to be opened in read-only mode; in practice it seems to be read/write mode, so you can write to it. (I suspect this is because FDs 0, 1 and 2 all refer to the same file description)
So echo text > /proc/PID/fd/0 just echoes text to the terminal.
To pipe input to the program, you would need to write to the other end of the pipe (actually a PTY, which mostly behaves like a pair of pipes). Most likely, whatever terminal emulator you're using (xterm, konsole, gnome-terminal) will have the other end open, so you could try writing to that.

How to fetch output of command of powershell with C++?

i implemented program of network statistics with help of powershell scrpit. the program is running successfully and giving me perfact output as well . below is my program.
int main(int argc, char *argv[])
{
string strPath = "C:\\Get-NetworkStatistics.ps1";
char str[50] = "C:\\Get-NetworkStatistics.ps1";
char command[500];
//access function:
//The function returns 0 if the file has the given mode.
//The function returns –1 if the named file does not exist or does not have the given mode
if(access(strPath.c_str(),0) == 0)
{
_snprintf(command, sizeof(command), "Start Powershell.exe -noexit Set -executionpolicy;.'%s';Get-NetworkStatistics",str);
system(command);
}
else
{
system("cls");
cout << "File is not exist";
system("pause");
}
return 0;
}
! here is the output of above program
as you can see the output is in the powershell windows.. i want to fetch all this data of powershell output and want to display it in console. how should it possible?
please help me..
Unless you need to do display the info in realtime as it becomes available, just redirect it to a file, then read that file from C++.
Since netstat was lobotomized in Windows XP SP 2 or thereabouts I can understand using Powershell.
But it may just be that netstat will serve your needs, and then you don't have to deal with any of that complication.
By the way, I recommend using a scripting language for scripting tasks. There is of course the complication that Powershell scripting is disabled by default, otherwise using the Powershell scripting facility would be indicated. But e.g. in this case a [cmd.exe] batch file would be more natural than doing its job from C++.
The Windows Script Host shell objects, available from JScript and VBScript, provide functionality for process execution with output grabbing.
There is a little snag in that you then have to poll the output, but I think it's still easier than doing this at the C/C++ API level.

How do I check if my program has data piped into it

Im writing a program that should read input via stdin, so I have the following contruct.
FILE *fp=stdin;
But this just hangs if the user hasn't piped anything into the program, how can I check if the user is actually piping data into my program like
gunzip -c file.gz |./a.out #should work
./a.out #should exit program with nice msg.
thanks
Since you're using file pointers, you'll need both isatty() and fileno() to do this:
#include <unistd.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
FILE* fp = stdin;
if(isatty(fileno(fp)))
{
fprintf(stderr, "A nice msg.\n");
exit(1);
}
/* carry on... */
return 0;
}
Actually, that's the long way. The short way is to not use file pointers:
#include <unistd.h>
int main(int argc, char* argv[])
{
if(isatty(STDIN_FILENO))
{
fprintf(stderr, "A nice msg.\n");
exit(1);
}
/* carry on... */
return 0;
}
Several standard Unix programs do this check to modify their behavior. For example, if you have ls set up to give you pretty colors, it will turn the colors off if you pipe its stdout to another program.
Try "man isatty", I think that function will tell you if you are talking to the user or not.
Passing stdin to select() or poll() should tell you if input is waiting. Under many OSes you can also tell if stdin is a tty or pipe.
EDIT: I see I'm going to have to emphasize the also part of the tty test. A fifo is not a tty, yet there might be no input ready for an indefinite amount of time.
Use isatty to detect that stdin is coming from a terminal rather than a redirect.
See the function "isatty" - if STDIN is a terminal, you can skip reading from it. If it's not a terminal, you're getting data piped or redirected and you can read until EOF.
An additional option you get with select() is setting a timeout for reading from stdin (with respect to either the first read from stdin or consecutive reads from stdin).
For a code example using select on stdin see:
How to check if stdin is still opened without blocking?