Home > Net >  Using stdin and stdout if no file is given in C
Using stdin and stdout if no file is given in C

Time:02-06

I have a program that copies a source file to a destination file.

In the event that only 1 or neither of these files are provided by the user, I'd like to use stdin or stdout.

For example: The source file name is not provided in command line arguments, but the destination file is. The program should read input from stdin and write to the given destination file.

I know of freopen() but I don't know how I should use it in this case.

Below is my boilerplate code for how I think the logic is done, but I can't find any examples of this that are helpful for me to learn. Any insight is appreciated.

char *src = NULL; (unless user provides in preceding code not shown)
char *dest = NULL; (^^)
        // open files based on availability

        // src and dest not provided, read from stdin and write to stdout
        if (src == NULL && dest == NULL) {
            FILE *in = freopen(src, "r", stdin);
            FILE *out = freopen(dest, "w", stdout);

            // TODO

            fclose(in);
            fclose(out);

            // src not provided, read from stdin
        } else if (src == NULL) {
            FILE *in = freopen(src, "r", stdin);

            // TODO

            fclose(in);

            // dest not provided, write result to stdout
        } else {
            FILE *out = freopen(dest, "w", stdout);

            // TODO

            fclose(out);
        }

CodePudding user response:

I tend to avoid freopen and use a different approach. I define two FILE * variables and either use fopen() if the filename is provided or set them to stdin or stdout as appropriate if not:

#include <stdio.h>

/* copying files: 0, 1 or 2 arguments */
int main(int argc, char *argv[]) {
    FILE *in = stdin;
    FILE *out = stdout;
    char *srcfile = NULL;
    char *destfile = NULL;
    int c;

    if (argc > 1) {
        srcfile = argv[1];
        if (argc > 2)
            destfile = argv[2];
    }
    if (srcfile && strcmp(srcfile, "-")) {
        if ((in = fopen(srcfile, "r")) == NULL) {
            perror(srcfile);
            return 1;
        }
    }
    if (destfile && strcmp(destfile, "-")) {
        if ((out = fopen(destfile, "w")) == NULL) {
            perror(destfile);
            return 1;
        }
    }
    while ((c = getc(in)) != EOF) {
        putc(c, out);
    }
    if (in != stdin)
        fclose(in);
    if (out != stdout)
        fclose(out);

    return 0;
}

CodePudding user response:

Just if statements that's it. Verify if the src is NULL, if so fopen(stdin, "r") but don't close it after or it will cause undefined behaviour (I'm talking about stdin).
For stdout you don't even have to open it so you can write in it just like that. Example:

int is_in = src == NULL;
FILE *in = fopen(is_in ? stdin : src, "r")

if (!is_in)
    fclose(in);
  •  Tags:  
  • Related