开发者

Reading a file name from piped command

So I'm trying to get the C program to read a filename from the command line in the following format: cat (filename path) | (program name)

i can get it to read the name of the input file when its entered as a command line argument, but it won't read from the concatenated argument

here's the code, right now its reading the name of the file as if written after the program name on the command line.

#incl开发者_运维问答ude <stdio.h>
#include <string.h>

//initialize file pointer
FILE *file;

//initialize global variables
#define DEFAULT_LEN 70

//main
int main(int argv, char *argc[]){

 //open File for reading
 file = fopen (argc[1],"r");
 //test for failure of file open, if failed, print message, quit
 if(file == NULL){
      printf("I'm sorry Dave, I'm araid I can't do that.\n");
  printf("Open the file \"%s\" that is.\n", argc[1]);
  return(0);
 }

 //read the first line of a file into an array
 char temp[DEFAULT_LEN]; //where the read data is put
 fgets(temp,DEFAULT_LEN,file); //stops at DEFAULT_LEN on \n

 //print out temp
 printf("%s\n", temp);

 //close file, return 0 for main
 fclose(file);
 return(0);
}

any help would be appreciated


The reason your program can't get the file name is because you're not giving it to it.

If you run your program as:

prog hello.txt

it's given the argument hello.txt in argc/argv.

However, what you're doing is:

cat hello.txt | prog

which means the shell is opening the file and feeding it into the standard input of your program. Actually, to be more accurate, cat is opening the file and the shell is simply connecting the standard output of cat to the standard input of prog.

One way around this is to check the number of arguments (argc is usually the count, argv[] the values, despite the roundabout way you have it in your code) and, if it's zero, argc == 1, read your file from standard input.

Only if an argument is given do you open that file and read it. That's the way a lot of UNIX utilities work:

od -xcb hello.txt        # will dump the file.
cat hello.txt | od -xcb  # will dump the file, but using standard input.
echo hello | od -xcb     # will dump your "hello" string.

Some even change their behaviour depending on how they're invoked, wc being one example - it shows the file name(s) if it knows them:

pax> wc -l qq.c
     29 qq.c
pax> cat qq.c | wc -l
     29
pax> wc -l *.c
      0 a b.c
    168 binmath.c
     49 qq-save.c
     29 qq.c
     11 qq2.c
      5 qqq.c
     18 xx.c
    280 total
pax> cat *.c | wc -l
    280

Note that last case - because all files are being presented over the single standard input stream, there's no way to tell how many files there are. wc will just tally up the entire contents of that stream.

Try this instead:

#include <stdio.h>
#include <string.h>

#define DEFAULT_LEN 70

int main (int argc, char *argv[]) {
    FILE *file;

    // Either select standard input or open the given file.

    if (argc == 1) {
        file = stdin;
    } else {
        file = fopen (argv[1], "r");
        if (file == NULL) {
            printf ("I'm sorry Dave, I can't do that\n");
            printf (" (open the file '%s', that is).\n", argv[1]);
            return 1;
        }
    }

    // Now you're connected to stdin or the file itself, no
    //  difference in handling them (unless you do weird fseek
    //  sort of stuff).

    char temp[DEFAULT_LEN];
    fgets (temp, DEFAULT_LEN, file);

    printf ("%s\n", temp);

    // Only close file if you opened it yourself.

    if (argc != 1)
        fclose (file);
    return 0;
}

This allows you to use both the file and standard input method as follows:

pax> prog prog.c
#include <stdio.h>

pax> echo hello | prog
hello


Piping content into a process does not put the values into argv; rather, it puts the values onto that process's stdin.

You need to check if argc is greater than 1. If it is, then argv[1] has the filename you've been given (well, the first argument to the program, anyway). If not, you need to read from stdin to get the filename.


To read from the contantenated, you need to read from STDIN

char c = (char)fgetc(stdin)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜