I want to pass a file into a c program.
If I am doing it in the IDE this arguments
./test string string < test.txt
return argc = 5, but on the terminal I am just getting argc = 3.
It seems, that its because of the "<" - symbol, I wanted to use this, to indicate that I am passing a file.
What does < mean? I am using Ubuntu with Tilix terminal
Redirection is performed by the shell, and is not (directly) visible to your program.
./test string string < test.txt
means,
Open test.txt for reading on file descriptor 1
Run ./test with the arguments string and string
The program run in point 2 will inherit the parent's file descriptors, so its standard input will be connected to the opened file handle (rather than the shell's current standard input, which could be your terminal, or a different file handle).
As an aside, you probably want to avoid calling your programs test, though as long as you don't forget to invoke it with an explicit path, this is harmless.
The < symbol will insert information from somewhere (a text file) as if you typed it yourself. It's often used with commands that are designed to get information from standard input only.
For example (using tr):
tr '[A-Z]' '[a-z]' < fileName.txt > fileNameNew.txt
The example above would insert the contents of fileName.txt into the input of tr and output the results to fileNameNew.txt.
Answer adapted from this page.
For similar information about all symbols, use this page
Related
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 am trying to, in C:
Read data from a file
Manipulate the data
Write manipulated data to another file
In the assignment requirements, it says to compile and run the program with the following commands:
gcc -o name name.c
./name inputFileName.ext > outputFileName.ext
I am unfamiliar with the " > " command. I have a couple of questions:
Online, it says that " > " redirects command output to a file, and I'm not sure exactly what "command output" means. I'm redirecting the output from my name.c file to the outputFileName.ext file. Does command output mean stdout? If so, which C keyword would I use to write information to the outputFileName.ext file from name.c as stdout?
When I open and read my input file, I need to access the file that was passed in from the command line. Does the " > " character count as another command line argument? Can I still access inputFileName.ext from main() with the statement " argv[1] " ?
Online, it says that > redirects command output to a file, and I'm not sure exactly what "command output" means.
"command output" refers to the stdout (Standard Output) stream of the program.
Do note that some shell commands are not separate programs but are actually shell builtins, though they'll still support output redirection. On Windows, most shell commands (like dir and del) are built-ins whereas on Linux/BSD/etc most shell commands are separate programs (like ls and mkdir)
If your program calls puts( "foobar" ); then running ./name from Bash will display "foobar" in your terminal emulator. But if you run ./name > file.txt then the "foobar" text will be written to file.txt and it will not be displayed in your terminal emulator.
Try it with the ls command, for example: ls -al > files.txt. This works on Windows too (dir /s > files.txt).
I'm redirecting the output from my name.c file to the outputFileName.ext file. Does command output mean stdout?
Yes.
If so, which C keyword would I use to write information to the outputFileName.ext file from name.c as stdout?
You don't. This is a shell/OS feature and is not part of C.
Let's clarify a few things:
>, < and a few other symbols (that are not relevant to your question) are control operators for your command line interpreter (a.k.a the shell). When the shell sees any of those, it assumes the command line arguments to your program are now finished. So in your case, your program will have argc=2 and argv = ["name ", "inputFileName.ext"].
The "redirection" thing means that whatever your program would normally write to the screen via the stdout (which is ulitized by default when calling printf() putchar(), puts()) will be written to the filename that comes after >. Your pogram is completely unaware of this fact. In your code, you should just assume you are printing on the screen. It is the responsibility of the one who executes the command to perform the redirection. (Also: "outputFileName.ext" does not need to exist, it will be created if it doesn't, but the redirection will override anything previously written in that file, so take extra care not to redirect to a .c file by accident or to your results of your previous execution, if you need them both)
< (not in your question, but closely related) works the opposite way around as you would imagine, with the program reading input from that file rather than from the keyboard. (obviously the file needs to exist now)
For the second part of your question, you can (and should) still access the name of the input file via the contents of argv[1]. You will open the file and read from it via some of the C functions that takes a file descriptor as an argument (like fscanf(), fgets(), getline()).
Finally, are you sure the command given to you is
./name inputFileName.ext > outputFileName.ext
and not
./name < inputFileName.ext > outputFileName.ext
?
The latter uses redirection both for input and for output, and you should not do anything different when reading, just read normally from stdin.
I am trying to not hardcode the name of the input file in my C program. I have all of the other components working when I hardcode the filename. But would like to be able to pass it a string filename.
I am trying to execute compile a file called Matrix.c and name its executable matrix.
So, in terminal, when I get to my working directory.
gcc -g Matrix.c -o matrix
then when I compile
./matrix
It doesn't have a filename passed to it so I am gonna check for that and have the user input a filename to load.
However, when someone passes the filename, should it be passed as:
./matrix filename.txt
or
./matrix < filename.txt
With the latter option, I can't seem to get the name of the argument passed to the function from argv[1] — it's just "(Null)".
I know this is very simplistic question. But am I just completely off my rocker? Is it something to do with me running on OS X El Capitan. I know I've used the '<' convention before.
The issue is how the shell works, mainly. When you use:
./matrix filename.txt
then the program is given two arguments — the program name and the file name. When you use:
./matrix < filename.txt
then the program is given just one argument — the program name — and the shell arranges for its standard input to come from the file (and the file name is not passed to your program).
Either can be made to work; you just have to decide which you want to support. What should happen if the user types ./matrix file1.txt file2.txt file3.txt? One version of conventional behaviour would be to process each file in turn, writing each set of results to standard output. There are plenty of alternative behaviours — most of them have been used by someone at some time or another. Reading from standard input when there is no file name specified is a common mode of operation (think cat and grep and …).
Arguments to a command are in argv[1 .. argc-1].
The redirect from '<' sends the contents of the file to the program's stdin.
A third way to get the filename would be to print "Enter filename: " and then read the string typed by the user.
I'm having difficulty writing a function in C that checks whether a user inputed file (via stdin) exists. For instance if the program is run as ./a.out <myfile.txt, I want it to return false if this file does not exist. I can do this by passing the file as an argument (i.e ./a.out myfile.txt)using fopen(), but not sure how to do this using 'stdin' (i.e ./a.out <myfile.txt)
Ok to clarify:
The larger program is supposed to take the contents of a text file and perform actions on it. The program must be run in the command line as ./a.out arg1 arg2 <myfile.txt. If user ran the program as ./a.out arg1 arg2 or ./a.out (i.e not specifying the file to perform actions on), I want to prompt the user to include a file (using stdin <, not passed as an argument).
Stdin might not be coming from a file at all. Even if it is, when the user types "< myfile.txt" at the command line, the shell swallows that part of the command, and never passes it to the program. As far as the program is concerned, it's an anonymous stream of bytes that might be from a file, a device, a terminal, a pipe, or something else. It is possible to query which of these you have, but even if you know it's a file you won't get the name of the file given on the command line, only an inode.
Since the shell is responsible for opening the file for redirection, it will refuse to execute the command if the file doesn't open.
Input redirection is something done by the shell, not your program. It simply attaches the file to standard input.
Hence, if you try to redirect input from a non-existent file, the shell should complain bitterly and not even run your program, as shown in the following transcript:
pax> echo hello >qq.in
pax> cat <qq.in
hello
pax> cat <nosuchfile.txt
bash: nosuchfile.txt: No such file or directory
In any case, your program generally doesn't know where the input is coming from, since you can do something like:
echo hello | cat
in which no file is involved.
If you want your program to detect the existence of a file, it will have to open the file itself, meaning you should probably give the filename as an argument rather than using standard input.
Or, you could detect the file existence before running your program, with something like the following bash segment:
fspec=/tmp/infile
if [[ -f ${fspec} ]] ; then
my_prog <${fspec}
else
echo What the ...
fi
The OS prevent calling your program since it can provide a valid stdin if myfile.txt does not exists. You program will not run thus there is no way you can signal the file is missing, and this diagnostics is done at the OS level.
If user ran the program as ./a.out arg1 arg2 or ./a.out (i.e not specifying the file to perform actions on), I want to prompt the user to include a file (using stdin <, not passed as an argument).
You could use OS-specific functions to check whether stdin is terminal. Checking whether it's file is a very bad idea, because it's very useful to pipe into stdin ... in fact, that's a major reason that there is such a thing as stdin in the first place. If you only want to read from a file, not a terminal or pipe, then you should take the file name as a required argument and not read from the orginal stdin (you can still read from stdin by using freopen). If you insist that you don't want to do it that way, then I will insist that you want to do it wrong.
In section 1.6 of 'The C Programming Language' (K&R) there is an example program and the authors state:
The output of this program ON ITSELF is
digits = 9 3 0 0 0 0 0 0 0 1, white space = 123, other = 345
Then there are many similar programs etc. including exercises. I understand everything about the logic of the code and can do the exercises, but how do I actually test my program on a file like the authors or many others on the web?
Edit: The question should be: How can I redirect the input of a file to the program?
The program in chapter 1.6 reads input from stdin. To make it read from a file, you can (on most operating systems) redirect stdin to be a file by running your program like this:
myprogram < somefile
Or you can pipe the content of a file to it like so:
cat somefile | myprogram
On windows, you'd use the type program instead of cat,
type somefile | myprogram
This is using re-direction. Instead of the input to the program coming from the keyboard it comes from a file.
At the DOS prompt:-
C:>myexe < filename
Get to the DOS prompt in Windows use the command shell. Or start Run.. and enter cmd
On a Mac this is called terminal (type "terminal" into Searchlight to get to it).
By default, your program will take input from stdin, which is a buffer which is filled based on input from your keyboard (by default). However, you can also tell your program to fill stdin from a text file instead.
Using a *nix based system, you can simply create a text file, and save it as whatever you'd like, "test_input" for instance. Fill it with the input that you'd like to pass to your program, save it, and then run your program like this:
./a.out < test_input
This is called redirection because you are "redirecting" (if you will) the input to come from a file, rather than the default (keyboard). It goes both ways, you can also redirect your output to a file, rather than stdout with the other angle bracket, '>'.
Using Visual Studio, and not popping open a command prompt to do something like the command above, you can use a C++ ifstream, put the text file in the local directory, and then simply use the ifstream everywhere instead of stdin:
ifstream sin("test_input.txt" , ifstream::in);
int value;
sin >> value;
You can output to a file using an ofstream.
Note that ifstreams and ofstreams are C++ objects, and can't be used in C. While you can write to files and read from files in C, it's a little trickier than simply replacing all instances of cout and cin. You actually have to think about what you are reading and writing :)