'how would i create a file output stream in c like stdout?

if printf uses stdout but how would i write a print function using my own output stream? i want to handle this stream with a OO-like structure but i can do that myself. is this possible? this for learning.

would something like this work - i didnt test this code:

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

FILE* stdout2 = NULL;

int init() {
    stdout2 = fopen("stdout.txt", "w");
    if (!stdout2) return -1;
    return 1;
}

void print(char* fmt, ...) {
    va_list fmt_args;
    va_start(fmt_args, fmt);
    char buffer[300];
    vsprintf(buffer, fmt, fmt_args);
    fprintf(stdout2, buffer);
    fflush(stdout2);
}

void close() {
    fclose(stdout2);
}

int main(int argc, char** argv) {
    init();
    print("hi"); // to console?
    close();
    return 0;
}

how would i get printf(char*, ...) print to the console? would i have to read the file in the same function?



Solution 1:[1]

Try use fdopen (see The GNU C Library: Descriptors and Streams).

#include <stdio.h>

int main(void) {

  int filedes = 3; // New descriptor
  FILE *stream = fdopen (filedes, "w");
  fprintf (stream, "hello, world!\n");
  fprintf (stream, "goodbye, world!\n");
  fclose (stream);

  return 0;
}

Compile with gcc as below, where 3 is the same as defined in filedes.

gcc -o teststream teststream.c && ./teststream 3> afile.txt && cat afile.txt

The result:

hello, world!
goodbye, world!

Solution 2:[2]

You can write to FILE*'s with fprintf, which will have the same semantics as printf.

int main(int argc, char** argv) {
    init();
    fprintf(stdout2,"hi"); // will print to file
    close();
    return 0;
}

Solution 3:[3]

If, inside init, you assign stdout to your own variable, the output will be to the console

void init() {
    stdout2 = stdout;
    if (!stdout2) return -1;
    return 1;
}

Solution 4:[4]

Thats mostly correct. You should use functions that use length parameters though for security/overflow purposes. Secondly, the console (i.e. stdout) is simply a file descriptor with an id of 0, stderr is 1. You can open file descriptors with fdopen


int main(){
    stdout2 = fdopen(stdout, "w");
    print("Hello World"); //This will print to console
    return 0;
}

Solution 5:[5]

This function will help you print to both the specified file and outstream (terminal). You have to specify the file pointer, and the rest is the usual format of printf.

void my_printf(FILE * fileptr, const char * string, ...){

    char inBuf[100];

    va_list args;

    va_start(args, string);

    vsprintf(inBuf, string, args);

    fprintf(fileptr, inBuf);
    printf("%s", inBuf);

    va_end(args);

}

Example:

I/P:
my_printf( `file pointer`, "Hello World, today is \"%d\"th June", 10);

O/P:
Hello World, today is "10"th June

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Daniel Marcos
Solution 2
Solution 3 pmg
Solution 4
Solution 5