Reputation: 19
I am trying to run the following in cmd
:
gcc my_mainFile
and then run the following:
a.exe 2 < file.ppm
Basically what it does is sees the value 2
, calls a specific function based on that, and uses the contents inside the ppm
file. However, I am unaware of how to access this file itself. I need to be using scanf()
to read the file, but I don't have the format clear.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if(*argv[1] - '0' == 2){
//Open and read contents of the file
}
}
Upvotes: 0
Views: 3731
Reputation: 84642
Many Linux utilities allow you to pass the filename to read as the first argument or read from stdin
by default. This allows you to read from a given filename, or to pipe or redirect output from another process to your code on stdin
. To implement the alternative, you can take advantage that stdin
has type FILE*
and simply check whether a filename argument has been provided to read (and if so, open and read from that file), or read from stdin
by default.
For example:
#include <stdio.h>
#define MAXC 1024 /* if you need a constant, #define one (or more) */
int main (int argc, char **argv) {
char buf[MAXC]; /* buffer to hold entire line (adjust MAXC as needed) */
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
while (fgets (buf, MAXC, fp)) { /* read each line of input */
int a, b; /* example variables */
if (sscanf (buf, "%d %d", &a, &b) == 2) { /* parse/validate values */
/* do what you need with your values */
printf ("a: %d b: %d\n", a, b);
}
}
if (fp != stdin) /* close file if not stdin */
fclose (fp);
return 0;
}
Above, fgets()
is used to ensure a complete line on input is consumed with each read, preventing stray characters from be left unread in your input stream that will cause read failure (or infinite loop) on your next attempted read. Any values needed from the line are parsed with sscanf
. This avoids a great number of pitfalls new C programmers fall into by attempting to read directly with scanf
or fscanf
before understanding how to detect and properly handle matching or input failures due to either a mismatch between the format specifier and input, or exhausting input before all specified conversions take place.
Examples
Piping input on stdin
:
$ printf "1 2\n3 4\n" | ./bin/readfileorstdin
a: 1 b: 2
a: 3 b: 4
Example Input File
$ cat dat/2x2.txt
2 4
3 5
Handling File Directly or on stdin
Reading file directly:
$ ./bin/readfileorstdin dat/2x2.txt
a: 2 b: 4
a: 3 b: 5
Redirecting on stdin
:
$ /bin/readfileorstdin < dat/2x2.txt
a: 2 b: 4
a: 3 b: 5
You don't have to do it this way, you can just read from stdin
directly and avoid checking whether a filename was given -- but this method provides a lot of convenience and flexibility for input handling in just a few extra lines of code.
Upvotes: 2