Let me start by saying this is associated with a homework assignment. However, this is a very small and relatively insignificant part of the assignment.
The C program receives input via command line arguments but it needs to be in the form:
$ ./program < input
How, would I go about receiving that input as a string? Each time I try to print out the 3rd argument from argv I receive this message:
input: No such file or directory.
< is a shell redirect - it is handled outside your program. What you'll see is the contents of the file name 'input' being send to your standard input stream. This is a common way for programs to operate, although they usually also handle being given a file name e.g. sed.
If I had to guess I would think the:
input: No such file or directory.
is coming from the shell, as it is unable to open the file specified: "input".
On the other hand, if you actually want the < input as arguments to your program, you can escape or quote them so the shell won't interpret them. (Escaping left as an exercise for the reader :-)).
The ./program < input syntax is a special shell syntax saying "Redirects everything in the file named input to the standard entry of the program".
To read the input, your program just have to use standard input reading functions, line fgets or scanf.
On *nix systems, there won't be a third element of argv. If you execute that command on almost any Unix-like shell, it will be similar to doing this:
cat input | ./program
So your ./program has only one element in argv, but it's stdin is the file input, so to read the file you would just read from stdin. Note that this is a perfectly valid way to design your program. Many Unix programs read from standard input if no files are given, so that you may pipe in input from other programs (or in this case, from files).
What comes after the < is not a command-line argument. The contents of the file will be piped into your program by the shell.
All you need to do is read from stdin and you'll get the contents of the file.
You need to escape the '<', otherwise shell will parse it, and program won't receive it in command-line.
If you're using bash, then:
./program '<' input
or
./program \< input
Other shells might do it differently (e.g. Windows' default, cmd.exe, uses ^ as escape character, not \).
This is a Unix shell thing. The form someprogram < somefile tells someprogram to run using somefile as its input. If you want to do something different involving the < symbol, you'll need to quote it.
The < means that the program will read it's standard input (stdin) from the named file (input). So just read from stdin (using fgets, fread, etc).
Leave off the '<'. You want command line arguments do this:
$ ./program -Dflag seven=ixnay FromDinger
In your application, try this:
int main( int argc, char **argv )
{
int i;
for( i = 0 ; i < argc ; ++i )
printf( "Arg %d = %s\n", i, argv[i] );
return 0;
}
You'll notice that the first argument is the name of the executable (at index 0), and your second argument (at index 1) will be "-Dflag"
Actually, this is a very common technique used in programming tournaments. The data your program needs is stored in a file, let's say data.txt , and then redirected to your application using the "<" on the shell, like this: ./program < data.txt
So, in your source code, what you need to do is something like this:
#include <iostream>
#include <string>
using namespace std;
int main(void)
{
string tmp;
string full_content;
while (cin >> tmp)
full_content += " "+tmp;
cout << full_content << endl;
}
.. and you'll get all the data from the file on a string (and separated by spaces).
That's one way to do it, I hope it helps.
[]'s
You can get it by reading stdin.
Related
I know, if ran in bash, my program is supposed to able to handle arguments like (where a.out is the name of file):
$ a.out <inputFile
Does this mean that inputFile is argv[1]? If so, what is the data type of argv[1] in case I need to pass it in to some other function? Would I read it using something like:
FILE *fopen( const char * filename, const char * mode );
OR
Does that mean I have to accept input from user getchar() or something?
How do I deal with such situations?
There's two ways to receive input:
Via STDIN, which is a pre-defined filehandle (fd 0 or STDIN_FILENO) you can read from at any time.
Via command-line arguments passed by argv
The shell interprets redirection operators to adjust what STDIN actually is, so by the time the program runs the only arguments left are:
"a.out"
The redirection is gone. It's just "piped" into STDIN.
Shell operators like <, > and | are interpreted by the shell before your program is run. The same goes for interpolation like $ variables and other shell-specific functions.
The command
./a.out < inputFile
isn't passing arguments to the program, instead if does redirection.
That means the shell will set up standard input (stdin, which e.g. scanf reads from) in your program to read from the redirected file.
To pass an actual argument to the program you need to run it as:
./a.out inputFile
In this case argc will be equal to 2, and argv[1] will be the string "inputFile". Which you can then pass on to e.g. fopen.
You need to pass a path to the c program then use fopen()
Using "<" means you are redirecting standard input of your process to be read from inputFile. So, all the standard read routines (getchar(), cin << ...) can be used.
If you omit "<", then inputFile becomes command argument and it is passed as part of char* argv[] to your main. After checking argc, validating file exists etc., you can use file reading routines, like fopen.
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'm using the cat command for a school project.
What i need is to give a txt file as input to my code and then evaluate the output (saved in a txt file).
So far i'm using this in my command line:
cat input_000.txt | ./main > my_output.txt
Where ./main is my C code.
The input_000.txt is structured like this:
0 a a R 3
1 a b L 4
4 c b R 1
ecc...
I have a certain number of lines made of 5 characters (with spaces between them).
How do i get the content of each line in my C code? I've been told so use standard input, but i've always used scanfonly from keyboard input.
Does it still work in this case?
And how should i save my output? I usually use fwrite, but in this case is everything managed by the cat command
That's how pipes works, it sets up so the output of the left-hand side of the pipe will be written to standard input for the right-hand side program.
In short if you can read input from stdin (like you do with plain scanf) then you won't have to do any changes at all.
Redirection works just about the same. Redirecting to a file (>) will make all writes to stdout go to the file. Redirecting from a file (<) will make all reads from stdin come from the file.
You can use getline (or scanf indeed) to read the stdin (fd = 0) and save it in a char* in your C code... Then you only need to write in the stdout (fd = 1) and your > will do the job to write in your file
What you need is something like this inside your function...
FILE *input = fopen("input.txt","rw"); //rw (read-write)
FILE *output= fopen("output.txt","rw"); //rw (read-write)
char inputArray[500];
char outputArray[500];
while(fscanf(input,"%s", inputArray) != EOF){
//read the line and save in 'inputArray'
//you can also use %c to find each caracter, in your case I think it's better...you can //save each caracter in a array position, or something like that
}
while(number of lines you need or the number of lines from your input file){
fprintf(output,"%s\n",output); //this will write the string saved in 'outputArray'
}
If you don't want to use it...then you can give your main.c the input using < and saving the output >
./main.o < input.txt > output.txt
(something like that, its not safer because the terminal could have the settings to use other type of charset...
I am trying to pass File1.txt ">" File2.txt as terminal arguments to my program in order to override the cat command. But for some reason, the program is not working. Although the argc is 4 in above defined case but still the condition in the program is not getting true. Here is the code:
int main(int argc, char *argv[])
{
int readbytes,fp;
char buf[1024];
if(argc==2)
{
fp=open(argv[1],O_RDONLY);
dup2(0,fp);
close(fp);
readbytes=read(STDIN_FILENO,buf,1024);
write(STDOUT_FILENO,buf,readbytes);
}
if(argc==4)
{
printf("inside4");
fp=open(argv[1],O_RDONLY);
dup2(fp,0);
close(fp);
fp=open(argv[3],O_WRONLY|O_CREAT|O_TRUNC,S_IRWXU);
dup2(fp,1);
close(fp);
readbytes=read(STDIN_FILENO,buf,1024);
//printf("%c",buf);
write(STDOUT_FILENO,buf,readbytes);
}
return 0;
}
I couldn't find a solution to this issue so I leave it to experts now.What is the reason for this problem?
NOTE:
For some reason when I send ./prog File1.txt > File2.txt to program, argc==2 condition is selected, however argc is 4. Why is that?
Regards
This is likely being caused by how you are running your program. Typing
./myProg foo > bar
will instruct most shells to run myProg with argument foo and save whatever is printed to stdout in a file named bar. To pass foo, >, and bar as command line arguments, use
./myProg foo \> bar
or
./myProg 'foo' '>' 'bar'
Side note: Because piping output into a file using > is part of the shell, not a program like cat itself, you likely shouldn't have to worry about it. Just write to stdout and the shell will handle the rest.
What do you mean by the condition in the program is not getting true? Are you saying that you don't see "inside4" printed to the terminal? There are a few things to consider. First, you do no error checking. We will have to assume that all of your open and dup2 calls succeed. I would expect that "inside4" is getting printed to the end of the output file. The reason for that is simply that printf does not actually write anything. It just stores the string "inside4" in a buffer, but that buffer is not written to the output until your program exits, and by that time the underlying file descriptor has been changed to the output file. The simplest fix is to append a newline to the output, and write printf( "inside4\n" ); In the normal setup, printing a newline causes the internal buffer to be flushed. You can also explicitly flush the buffer after calling printf by calling fflush.
I am developing a application that reads from the stdin and does some computations on the data. I have currently set on Eclipse's Program's Arguments the following string:
< "input.txt"
where input.txt is the file I want to read from, but it doesn't seem to be working, as with the following code only "abc" is being printed:
char c;
printf("abc\n");
while ((c = getchar()) != EOF) {
printf("%c", c);
}
What am I doing wrong?
The < symbol is not a program argument, its a shell operator - it only works in a shell that understands it as part of parsing a command line.
Apparently, Eclipse doesn't use a shell to start up a Java programs and it doesn't itself process shell operators like < for starting up. I'll bet if you printed the command arguments in your program, you'd see < and input.txt. A shell would have processed them and not passed them to the program.
Unfortunately, I don't see anything in my version of Eclipse that suggests how to redirect the standard input to come from a file.