how would i create a file output stream in c like stdout?
Asked Answered
O

5

6

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?

Obligee answered 27/11, 2011 at 20:49 Comment(1)
Your question is a bit confusing... Your code, although ugly :-), is fine in as much as it works. I would highly recommend return 0 on success of functions which return int type (instead of 1) ... what do you want to do with print("hi")? do you want to print it to console AND to a file? If so that can be done quite a bit more efficiently than what you are doing.Hafler
C
8

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!
Chalice answered 27/7, 2016 at 22:13 Comment(0)
E
0

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;
}
Edmond answered 27/11, 2011 at 20:52 Comment(0)
N
0

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;
}

Nanaam answered 27/11, 2011 at 20:53 Comment(2)
ok i understand that but when i use the print function it is going to the file which is good but does printf use another file like stdin to put it on the console?Obligee
fdopen returns a FILE* see: mkssoftware.com/docs/man3/fdopen.3.asp . That means that you can use a FILE* to write to the console. If you are asking how printf itself is implemented, I believe it uses basic functions like putcharNanaam
S
0

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;
}
Selfconfidence answered 27/11, 2011 at 20:57 Comment(7)
stdout is usually #defined to the fd number: 0 meaning that you have to fdopen it firstNanaam
@chacham15: see 7.16.1/3 in the C99 Standard. stdout is an "expression of type pointer to FILE"; there is no reference about it being macro or references to "fd"s or even "file descriptor"sSelfconfidence
ah, well i am used to pre c90 standards (usually for the sake of portability)Nanaam
@chacham15: You are thinking of STDOUT_FILENO which is always defined to 0. There was no pre-c90 standard other than K&R first edition, in which stdin, stdout and stderr are "file pointers".Illailladvised
just tested this on my system, using gcc3 with cygwin stdout is #defined to 0Nanaam
@Nanaam actually STDOUT_FILENO is 1; STDIN_FILENO is 0; and for completeness STDERR_FILENO is 2Hafler
huh? im lost then, anyone have an explanation?Nanaam
O
0

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
Odin answered 3/6, 2022 at 3:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.