Linux Redirection to C program - File Reading

2019-08-17 20:01发布

问题:

I want to read lines of numbers from the text file (filename.txt) using a function in C.

How do I open this file (provided the filename is only given through a redirection on Unix)?

i.e. ./cfile < filename.txt

int main (void)
{
  char filename[20];
  fgets(filename, 19, stdin);
  FILE *fp;
  fp = fopen(filename, "r");
}

So, would this be correct; also, how do I access one line at a time from the file (all I know is EOF has to be used somewhere)?

回答1:

The contents of filename.txt gets redirected to the standard input of the executable. Therefore you could simply write your code as follows:

#include <stdio.h>

#define MAXLEN 256 // Maximum number of characters in a line

int main() {
   char line[MAXLEN];
   while (fgets(line, MAXLEN, stdin)) {
       printf("Line %s", line); // Do something with the line
   }
   return 0;
}


回答2:

< is used to redirect the standard input from a file instead of the keyboard, in this case you don't need fopen:

int main(void)
{
    char buffer[100];

    /* Don't use magic numbers with fgets, sizeof buffer is the correct size */
    while (fgets(buffer, sizeof buffer, stdin)) {
        printf("%s", buffer);
    } 
    return 0;
}

You can fopen a file using an argument passed to main:

int main(int argc, char *argv[])
{
    char buffer[100];
    FILE *fp;

    if (argc == 2) {
        fp = fopen(argv[1], "r");
        if (fp == NULL) {
            perror("fopen");
            exit(EXIT_FAILURE);
        }
        while (fgets(buffer, sizeof buffer, fp)) {
            printf("%s", buffer);
        } 
        fclose(fp);
    }
    return 0;
}

Launch it using ./cfile filename.txt (without the redirection).



回答3:

On Linux, when you run a program, 3 files are opened for the standard input (fd 0), output (fd 1) and error (fd 2). By default, these files are your terminal :

 % cat & 
 % ls -l /proc/`pidof cat`/fd
total 0
lrwx------ 1 max max 64 mars  21 10:34 0 -> /dev/pts/0
lrwx------ 1 max max 64 mars  21 10:34 1 -> /dev/pts/0
lrwx------ 1 max max 64 mars  21 10:34 2 -> /dev/pts/0

But you can also specify the file that should be used with <, > and 2> :

 % cat > /dev/null &        
 % ls -l /proc/`pidof cat`/fd
total 0
lrwx------ 1 max max 64 mars  21 10:36 0 -> /dev/pts/0
l-wx------ 1 max max 64 mars  21 10:36 1 -> /dev/null
lrwx------ 1 max max 64 mars  21 10:36 2 -> /dev/pts/0

So, the file is already opened and is respectively in the FILE* stdin, stdout and stderr. For this last example it's in stdout but in your case (with <) it will be in the FILE* stdin.

So basically, you don't need to do the fopen, and you can use stdin.