-1

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

AProgrammer
  • 51,233
  • 8
  • 91
  • 143
Tim4497
  • 340
  • 3
  • 19
  • 3
    `<` is interpreted by the shell as redirection and you have to quote it to avoid that. – AProgrammer Nov 21 '19 at 14:22
  • 1
    ... but if you quote it, `test.txt` won't be redirected into the program's input anymore – Jabberwocky Nov 21 '19 at 14:26
  • @Jabberwocky, I wonder if it is related to [this question](https://stackoverflow.com/questions/58975330/impelmenting-unix-commands-through-fork-pipes-file-descriptor-dup2-exec). – AProgrammer Nov 21 '19 at 14:28
  • @Jabberwocky at the moment im not using `<` for the file input, I'm opening the file with fopen(). I didnt know that you can use `<` for file redirection! THX – Tim4497 Nov 21 '19 at 14:30
  • @AProgrammer haha nope – Tim4497 Nov 21 '19 at 14:32
  • The shell takes care of the `<`, you don't need to do anything in your program, just read from stdin using the standard functions such as `scanf`, `fgets` or whatever. It automatically redirects the content of `test.txt` into the standard input, see answer below. – Jabberwocky Nov 21 '19 at 14:35
  • 1
    If you really want to use `<` as a command line argument, use e.g. `./test string string "<" test.txt` as your command line. (There are different options to quote the `<`.) – Bodo Nov 21 '19 at 14:41
  • @Tim4497 : Maybe it would be a good idea if you posted your C program here as well. – user1934428 Nov 21 '19 at 15:04

2 Answers2

5

Redirection is performed by the shell, and is not (directly) visible to your program.

./test string string < test.txt

means,

  1. Open test.txt for reading on file descriptor 1
  2. 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.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • how can I allocate the right amount of storage for the buffer when I'm doing `fgets()`? Can I still get the size of the file connected with `stdin`? – Tim4497 Nov 21 '19 at 14:46
  • No, you can't know how much data is coming in from a stream in advance. The usual solution is to dynamically allocate space as required, but I'm guessing are probably not there yet in terms of C skills. If you can use a higher-level language, you don't have to worry about these things. – tripleee Nov 21 '19 at 14:51
  • And you should not be using `fgets` at all; see e.g. https://stackoverflow.com/questions/16323185/why-is-the-fgets-function-deprecated – tripleee Nov 21 '19 at 14:54
  • 1
    @tripleee : I don't see why `fgets` should not be used. In the link you posted, some people claim that the function is deprecated, but others (in the accepted answer of the page you linked to) say that this is not true. – user1934428 Nov 21 '19 at 15:03
  • @Tim4497, if `stdin` is a file, you can get its size; if it is a pipe or a terminal, you obviously can't. – AProgrammer Nov 21 '19 at 15:08
  • @Tim4497 You can use [getline()](http://man7.org/linux/man-pages/man3/getline.3.html) which automatically allocates enough space for any line. It's not standard C, but it's POSIX and Linux so you have it available. – Shawn Nov 21 '19 at 15:41
0

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

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • `tr '[A-Z]' '[a-z]'` will replace `[` with `[`, `A` with `a`, etc. This is not *wrong* per se, but replacing the square brackets with themselves is rather pointless and redundant. – tripleee Nov 21 '19 at 14:37