Standard input and output in c - c

I have a problem with stdout and stdin .when i store data by using stdout i cant getback the same data using stdin . so please help me how can i solve my problem.
Ram

Data you write to stdout will not be automatically available to stdin. Data written to the stdout stream is available to be read by whatever process is connected to that stream. Normally that is the terminal or console where the program was started. It can also be another process that was connected to the first one through a pipe or it can be a file when redirection was used.
If you want to read the data your program wrote to stdout via stdin on a subsequent run you can use redirections like this
$ program > data.out
Will store anything that is written to stdout in the file data.out. Then,
$ program < data.out
... will make the contents of data.out available to the program in stdin
Please post your code and some more detailed description of what you are trying to do if this isn't what you were trying to achieve.

Related

How can I access the file in C when the user used the '<' command on the shell?

I am trying to make a program that can process sentences in C in the POSIX environment. Assume that my program's name is "test". If the user entered just "./test", then my program will ask the user to enter some sentences. This one so far is easy.
However, if the user entered "./test < file.txt", the program should get the characters from that txt file. I do not know how I can get the characters of the file in C. I tried something like file = open(argv[2]);, but it did not work.
I will really appreciate it if you give me the answer to this question.
TL;DR: If you start your program like
./test
and you have to type in the input, then exactly the same program will read from file.txt if you start it as
./test < file.txt
Longer explanation starts here. (The following explanation is not 100% precise, but shall help to get an understanding what is going on in principle.)
In a C program you can open files with fopen. As a return value, fopen gives you a FILE pointer. However, when you start a program under Unix, three FILE pointers are already available. These default FILE pointers are stored in variables named stdin, stdout and stderr.
Of these, stdin can be used to read from, stdout and stderr can be written to. And, stdin is used as default in several C library calls, like, gets or scanf. Similarly, stdout is used by default for calls like printf.
Now, although they are called FILE pointers, they can in fact represent other things than just files. stdin could be a file, but it can also be a console where you can type in stuff.
This latter scenario is what you observe when you start your test program from the shell with the command
./test
In this case, the test process will be started with stdin just using the console from the shell from which you started the test program. Therefore, if in your test program you call, say, gets(), then your program will implicitly read from stdin, which represents the console input that was inherited from the shell. Consequently, in this case the user has to provide input by typing it in.
Now let's look at what happens if you start your process from the shell in the following way:
./test < file.txt
Here, the shell does a bit of extra work before it actually creates your test process. This is because the < file.txt part of your command line is interpreted by the shell - this is not passed as arguments to your program. Instead, what the shell does is, to open the file.txt and, when the test process is started, hand the opened file.txt over to the process such that in your test process stdin is connected to file.txt.
Then, the call to gets() in your program will again read from stdin, but this time stdin is not the console. This time stdin really corresponds to a file, that is, file.txt.

I cannot write to stdin with /proc/{pid}/fd/0

I have this program:
#include <stdio.h>
int main() {
char buf[10];
puts("gimme input:");
fread(buf, 1, 10, stdin);
printf("got %s", buf);
}
When I run this and open another terminal I try to write to stdin:
echo "ASDFASDFASDF" > /proc/{pid}/0
ASDFSADFSADF gets printed on the terminal that is running my C program, but fread still doesn't return until I type in the actual terminal. It also does not print any of the text that I wrote to /proc/{pid}/0
Is there something else I have to do to programatically input text to stdin?
If stdin is a terminal, then writing something to stdin will write to the terminal. Reading from the terminal will read whatever is typed into the terminal, not what's written to the terminal. This is just how terminals work.
If you want a program to read from something other than a terminal, you have to direct that to happen. Or, if you want to use a virtual terminal that you can put information into it and have it be read out, you have to direct that to happen.
Probably the simplest solution is to create a pipe with mkpipe and have the program read from the pipe rather than a terminal.
When you execute the echo command output-ing to the File Descriptor 0 you're just sending text. If you check the file descriptor using ls -l probably it is pointing to an device TTY or PTY/PTS. If you check the FD type using lsof it will be tty. It means you need to interact with this FD such as TTY.
Basically you need to simulate the input to get the expected behavior.
You can do this by calling the kernel tool ioctl.tiocsti(). I added a python code into the following similar question: Writing to File descriptor 0 (STDIN) only affects terminal. Program doesn't read

Why is it possible to write() to STDIN?

I have the following code:
int main()
{
char str[] = "Hello\n";
write(0, str, 6); // write() to STDIN
return 0;
}
When I compiled and executed this program, Hello was printed in the terminal.
Why did it work? Did write() replace my 0 (STDIN) argument with 1 (STDOUT)?
Well, old Unix systems were originaly used with serial terminals, and a special program getty was in charge to manage the serial devices, open and configure them, display a message on an incoming connexion (break signal), and pass the opened file descriptors to login and then the shell.
It used to open the tty device as input/output to configure it, and that was then duplicated in file descriptors 0, 1 and 2. And by default the (still good old) stty command operates by default on standard input. To ensure compatibility, on modern Linuxes, when you are connected to a terminal, file descriptor 0 is still opened for input/output.
It can be used as a quick and dirty hack to only display prompts when standard input is connected to a terminal, because if standard input is redirected to a read only file or pipe, all writes will fail (without any harm for the process) and nothing will be printed. But it is anyway a dirty hack: just imagine what happens if a caller passes a file opened for input/output as standard input... That's why good practices recommend to use stderr for prompts or messages to avoid having them lost in redirected stream while keeping output and input in separate streams, which is neither harder nor longer.
TL/DR: if you are connected to a terminal, standard input is opened for input/output even if the name and standard usage could suggest it is read only.
Because by default your terminal will echo stdin back out to the console. Try redirecting it to a file; it didn't actually write to stdout.
Are you confusing write with fwrite? The first parameter in write is a "file descripter", but it's not stdin. Try doing an fwrite to stdin -- it doesn't happen.

How to interrupt standard input stream for another

This problem maybe a little bit hard to state. For example, a program receive a string from stdin, but it need a interactive input from user, like this:
echo "Some text to handle later after command is specified" | a.out
And in the beginning of the program:
printf("Please input command first");
scanf("%s", &cmd);
/* Some Code Here */
/* process "Some text to handle later after command is specified" */
Is there a way to "suspend" previous input stream and wait for the scanf's ones?
The standard does not specify any way to get interactive user input besides reading from stdin. Since your stdin is occupied with a pipe, you need to tread an implementation-specific path.
For Unix-like systems that would be a special file named /dev/tty. fopen it and use normal stdio functions.
On Windows you probably need to call Console API.
Threre's no guarantee a program is attached to any interactive device, so prepare to fail.
Note that it's considered bad style to write programs this way. If there's any user input expected, a well-witten program should just use stdin. All other input streams should then be passed as filenames via command-line arguments.
When using pipes, the shell sets up the programs stdin to be from the output of the previous command. So reading should not be a problem.
The problem here is that you should not print any output if the input is from a pipe (or redirection). This can be done by checking the result of the isatty function:
if (isatty(fileno(stdin)))
{
/* Only print prompt if input is an interactive terminal */
printf(...);
}
scanf(...);
Or am I misreading you, in that you want to read both from the user, and from the pipe? Then you probably have to open a direct connection to the terminal.
For this you could use ttyname to get the name of the TTY device of stdout and open that device for input to read the user input. That won't work if the stdout is leading to a pipe (or is being redirected) as well.

Read file to standard in for parser

I am trying to implement a shell program in a linux environment. The part I am having trouble with is reading a setup_file inside of a shell before running the shell, to do things like set environment variables.
Currently the shell has a parser_results = parse() function which does a "getchar" and waits until the user types something into stdin, then does an execute(parser_result) which executes the command using the output of the parser.
What I want to do is to read the setup_file which has commands inside of it, have the parser read them in and give me the data structures I need. Then I can run execute.
My question is is how do I redirect the contents of the file to stdin? And how do I call the parser to parse this redirected input? I have been playing with dup and dup2 to no avail.
Short answer (to the question 'how do I redirect the contents of the file to stdin') is "You Don't".
You revise your input function to read from a given file stream instead of stdin, and then for reading from the file, you open it and pass that file pointer to your parsing code (and close when the parsing code is done), and then when you're ready for user input, you call the parsing code with stdin instead of the file. That saves fiddling with stdin.

Resources