I need to write a C program (myprogram) which checks output of other programs. It should basically work like this:
./otherprogram | ./myprogram
But I could not find how to read line-by-line from stdout (or the pipe), and then write all this to stdout.
One program's stdout becomes the next program's stdin. Just read from stdin and you will be fine.
The shell, when it runs myprogram, will connect everything for you.
BTW, here is the bash code responsible:
http://git.savannah.gnu.org/cgit/bash.git/tree/execute_cmd.c
Look for execute_pipeline. No, the code is not easy to follow, but it fully explains it.
Create an executable using:
#include <stdio.h>
int main()
{
char line[BUFSIZ];
while ( fgets(line, BUFSIZ, stdin) != NULL )
{
// Do something with the line of text
}
}
Then you can pipe the output of any program to it, read the contents line by line, do something with each line of text.
Related
So I understand that to read and print out a line of text you can just use printf, scanf and type it out. However what if I want to print out a text file without typing them out in terminal? And I don't mean using fopen(filename, "r") where you can only open a specific file. I think this is called redirection but I'm having trouble understanding it. Something along the line as the below input example:
./myprogram < input.txt
Here is a redirection cheat sheet. The line that interest us is:
cmd < file: Redirect the contents of the file to the standard input (stdin) of cmd.
Here a simple example that will print the content of your input.txt file. Compared to manual input, the program will never wait and will loop until the end of the file is reached (Note: there are cases where there is no end, you might want to add alternative break condition).
#include <stdio.h>
int main(void)
{
char buffer[100];
while (fgets(buffer, 100, stdin))
printf("%s", buffer);
return (0);
}
./myprogram < input.txt will print your input.txt
./myprogram will wait for your manual input and print what you just typed.
This is not exactly what you asked but you can put the filename as argument and get it in argv[1] and then use fopen
I am working on a school project in which we have to do some operations (select, min, max) on a table saved in .txt file.
The problem is that we can't use common functions such as fopen, fscanf, fclose.
The program will be launched from command line like this: .\project.exe select parameters <table.txt
Do you have some ideas how to get content of the .txt file to stdin without using fopen?
Thanks.
You do not need to open the file - the operating environment will do it for you.
When your program is called with <table.txt, your standard input is switched to read from that file instead of the keyboard. You can use scanf to read the data, and do not worry about opening and closing the file.
Same goes for the output of your program and the >table_out.txt redirection: rather than printing to the screen, printfs in your program would be writing to a file, which would be automatically closed upon your program's exit. Of course if you need to print something to the screen when your output is redirected, you can do so by printing to stderr (e.g. fprintf(stderr, "Invalid table format\n").
There are few ways to acomplish this.
Reading STDIN
I guess the teacher wants this method in particular. The idea is reading standard input rather than particular file.
In C++ you can simply read the stdin object. Here's an example:
#include <stdio.h>
#include <string.h>
int main(void)
{
char str[80];
int i;
printf("Enter a string: ");
fgets(str, 10, stdin);
/* remove newline, if present */
i = strlen(str)-1;
if( str[ i ] == '\n')
str[i] = '\0';
printf("This is your string: %s", str);
return 0;
}
Source: http://www.java2s.com/Code/C/Console/Usefgetstoreadstringfromstandardinput.htm
Using system utils
You can call "type" util # Windows (not sure about it) or "cat" util in Linux as a subprocess to read some partticular file. But this is rather a "hack", so I do not recommend using this one.
I am trying to get a basic understanding on how to use fputc in C. I have read some documentation that is out there and believed I had it right. But every time I try to use the script I wrote by executing ./fputc > test.txt where text.txt is a text file with one line of text.
This is my script:
int
main(int argc, char **argv){
int ch;
FILE *input;
input = fopen("text.txt", "w+");
while ((ch = getchar()) != EOF){
fputc(ch, input);
}
fclose(input);
return 0;
}
I get no errors on compilation and for some reason the script does not reach EOF at the end of the text file. Shouldn't the getchar return EOF when it reached the end of the text file?
The text (text.txt) file does not appear to be edited, although it is created. So somewhere in my while loop something is going wrong.
I am new to C programming (if you couldn't tell) and this little script has me befuddled.
Any help would be appreciated, or any links to sites with further detail would also be great.
Cheers,
S.
What you in essence say is:
Console: Run my_program and write anything it outputs to test.txt.
Program: Open text.txt and write any input to stdin to that file.
Your console normally have three standard streams stdin, stdout and stderr. These streams you can redirect. If you are on Windows also look at i.e. redirection.
When you say ./my_prog > test.txt, what you tell your console, (not my_prog), is to write anything my_prog writes to stdout to the file test.txt.
If you in your code say i.e. printf("Hello");, then Hello would be written to the file test.txt.
If you had turned your redirection around by saying ./my_prog < test.txt instead, would be; stream the file test.txt to my_prog. Which, in turn, if there was any text in test.txt would result in a copy of test.txt to text.txt.
Now in your code you say:
int main(void)
{
int ch;
FILE *input;
/* Here you open a handle to the file text.txt for reading and writing */
input = fopen("text.txt", "w+");
while ((ch = getchar()) != EOF) { /* get next char from stdin */
fputc(ch, input); /* write that char to the handle input */
}
fclose(input); /* close the handle */
return 0;
}
So what happens, the way you run it, is:
In your code:
Open text.txt
Wait for input (data entered to stdin) - typically user entering text to console, passed to program when Enter is pressed.
In console:
Redirect anything from my_prog to test.txt.
You say:
the script does not reach EOF
Well, as it reads from stdin it will only (not without exception) get EOF under two conditions.
If you redirect a file to your program. I.e. ./my_prog < foo.txt (notice <, not >).
- What would happen then is that my_prog would read the data from the file foo.txt and when that file ends your program would receive a EOF. And, hence quit.
If you manually enter EOF to stdin.
- On Linux and OSX Ctrl-D, on Windows Ctrl-Z
Now, if you test this by typing text to console remember that write actions like fputc()is buffered. What this mean is that the data is not written to the file right away, but only when a given amount of data is in buffer, fflush() is called, stream is closed, you turn off buffering, etc.
Also; if you run your program. Enter text, enter some more text, and then hit Ctrl-C to abort the program it is a big chance you end with no data in your text.txt.
The reason for this is that the program is killed and thereby fclose() never called, and hence no flush to file.
On your further endeavors in programming it would be a very good idea to make a habit of not presuming anything. I.e. do not presume fopen() is OK.
FILE *fh;
char *outfile = "foo.txt";
if ((fh = fopen(outfile, "w")) == NULL) {
fprintf(stderr,
"Unable to open file %s\n --",
outfile);
perror(" fopen() ");
return 1;
}
Most functions has a way to check if operation was a success. I.e:
if (fputc(ch, fh) != ch) { err ...
This will make your code a lot safer, give you hints on where it fails etc.
Some links:
Look at redirection links at top of post.
Look at the functions in stdio.h (good overview), stdio.h (examples etc.). I.e.:
stdin
stdout
stderr
fopen()
fflush()
setvbuf()
setbuf()
...
getchar returns the next character from the standard input (stdin).
It is equivalent to getc with stdin as its argument.
Hence, your code reads from standard input instead of FILE* input.
Use fgetc here.
fgetc returns the character currently pointed by the internal file position indicator of the specified stream. The internal file position indicator is then advanced by one character to point to the next character.
So, Use fgetc to read from a file:
while ((ch = fgetc(input)) != EOF)
your program and the shell are both writing the same file. you should remove the output redirection > test.txt from your command line
I've searched high and low, but can not find the answer to what I would've thought to be a rather simple question. I'm rather new to C, and due to the restrictions placed on me during this project I'm having a bit of trouble figuring out how to do this.
I am trying to read in text from a text file, and store that data in an array. Simple enough. HOWEVER, I'm forced to do so by using the command line operator '<' and to redirect the stdin to the text file.
The only way I can seem to figure out how to properly open a file and perform the subsequent operations is the following:
#include <stdio.h>
FILE *fr;
main()
{
fr = fopen ("mytext.txt", "r"); /* open the file for reading */
The problem with that is that I can't seem to get the first parameter of fopen() to be the filename provided by the stdin '<'. It only works if I explicitly type a string in for the parameter. For example, if I were to run
myprog.o < mytxt.txt
how could I pass the name of the text file provided by that stdin redirection to the fopen function? Or is there a different/better way to do what I'm trying to do?
Thanks in advance.
You need to read from stdin instead of trying to open the file directly.
This is because of how redirection works - think of it a bit like this:
The file is opened (for purposes of demonstration, let's say fopen is used for this).
The existing stdin is closed. It no longer refers to a terminal or similar construct.
stdin is replaced with the open file in step 1.
Any reads from stdin now work directly from the input file.
By using input redirection you can permit your user to either redirect a file or directly type content into your program.
As for your actual problem, you might be better off passing the filename as an argument to your program. You would use argv and call your program like so:
myprog.o mytxt.txt
In this case, argv[1] will be mytxt.txt.
A C program never sees the redirection because it is handled by the shell. The C program should look at argc and read from stdin if no args are given or from the given files otherwise.
There is a standard FILE* handle declared within <stdio.h> that points to the standard input for the executing process. Such file handle is called stdin.
If all you ever want this program to do is read from standard input, then you don't need to open any files. The OS and C libraries will handle opening and closing the file for you.
So to read a file in from standard input, and write it back out, try something as simple as
#include <stdio.h>
int main( int argc, char ** argv ) {
int ch = getchar();
while ( ch != EOF ) {
putchar( ch );
ch = getchar();
}
}
As you can see, no opening or closing of files. putchar and getchar write to stdin and stdout relatively.
If you want to be more explicit, you can use the predefined file handles.
int ch = fgetc( stdin );
while ( ch != EOF ) {
fputc( ch, stdout );
ch = fgetc( stdin );
}
You should look up printf() and fprintf(), scanf() and fscanf(), and all the other wonderful stdio functions.
I am trying to run a script inside my C program using system() command. Inside main(), I run the script and it returns the results. How can I put the result of the script in some string and check for conditions? I know I can do it with files but was wondering if its possible to put the result into a string.
Sample would be like:
main()
{
system("my_script_sh"); // How can I get the result of the my_script_sh
}
You can't use the system command for that. The best thing to do is use popen:
FILE *stream;
char buffer[150];
stream = popen("ls", "r");
while ( fgets(buffer, 150, stream) != NULL ){
// Copy the buffer to your output string etc.
}
pclose(stream);
Use popen() and read the stream into a char * buffer.
Well the easiest thing to do would be to take system("my_script_sh") out of your program and invoke the program from the shell with a pipe -- e.g.: my_script_sh | ./your_c_program and then your C program just reads from stdin (file descriptor 0).
If that is not possible, then have a look at man 3 popen. Basically, you use popen instead of system and it gives you a file handle that you can read from to get the output of the program.
Here are a few links that might be useful:
http://pubs.opengroup.org/onlinepubs/009695399/functions/popen.html
http://www.crasseux.com/books/ctutorial/Programming-with-pipes.html
http://www.metalshell.com/source_code/23/Popen.html
http://tldp.org/LDP/lpg/node12.html