如何在C语言中创建类似于stdout的文件输出流?

6
如果printf使用stdout,那么如何编写一个使用自己的输出流的打印函数?我希望使用类似OO结构的方式来处理这个流,但我可以自己做到。这种情况是否可能发生?我是想学习这方面的知识。
像这样的代码是否可行 - 我没有测试过这段代码:
#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;
}

我应该如何使printf(char*, ...)函数将内容打印到控制台上?我是否需要在同一个函数中读取文件?

你的问题有点令人困惑... 尽管你的代码有些丑陋 :-),但它能正常工作。我强烈建议在返回 int 类型的函数成功时使用 return 0(而不是 1)... 你想用 print("hi") 做什么?你想将它打印到控制台和文件中吗?如果是这样,那么可以比你现在做的更有效率。 - Ahmed Masud
5个回答

8

尝试使用fdopen(参见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;
}

使用以下gcc编译,其中3filedes中定义的相同。
gcc -o teststream teststream.c && ./teststream 3> afile.txt && cat afile.txt

结果如下:
hello, world!
goodbye, world!

0

这个函数将帮助您同时打印到指定的文件和输出流(终端)。您必须指定文件指针,其余部分是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);

}

例子:

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

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

0

你可以使用 fprintf 向 FILE* 写入内容,其语义与 printf 相同。

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

0

这基本上是正确的。为了安全和溢出的目的,您应该使用带有长度参数的函数。其次,控制台(即stdout)只是一个ID为0的文件描述符,stderr为1。您可以使用fdopen打开文件描述符。


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


我明白了,但是当我使用print函数时,它会输出到文件中,这很好,但是printf是否使用另一个文件(如stdin)将其输出到控制台? - evolon696
fdopen返回一个FILE,请参见:http://www.mkssoftware.com/docs/man3/fdopen.3.asp。这意味着您可以使用FILE写入控制台。如果您想知道printf本身是如何实现的,我认为它使用像putchar这样的基本函数。 - chacham15

0
如果在init中将stdout分配给自己的变量,则输出将显示在控制台上。
void init() {
    stdout2 = stdout;
    if (!stdout2) return -1;
    return 1;
}

1
stdout通常被定义为fd号码:0,这意味着您必须先fdopen它。 - chacham15
@chacham15:请参见C99标准中的7.16.1/3。stdout是“指向FILE类型的指针表达式”;没有关于它是宏或关于“fd”甚至“文件描述符”的引用。 - pmg
啊,我习惯于使用预C90标准(通常是为了可移植性)。 - chacham15
@chacham15:你在考虑的是STDOUT_FILENO,它总是被定义为0。除了K&R第一版之外,没有预先c90标准,在其中stdinstdoutstderr是“文件指针”。 - caf
我在我的系统上进行了测试,使用带有Cygwin的gcc3,stdout被定义为0。 - chacham15
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接