c - 如何同时输出到控制台和文本文件以使它们相同

标签 c file-io text-files

以下代码创建随机数表并将其打印到控制台上。如何修改我做的createtxt函数,让控制台的输出同时生成到文本文件中。

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


FILE* createtxt(char* fnam){
    FILE* ofp;
    ofp = fopen(fnam, "w");
    if (ofp == NULL) {
        printf("Cannot open output file %s\n", fnam);
        exit(EXIT_FAILURE);
}

void closetxt(FILE* ofp){
    fclose(ofp);
}

int main (void){
    printf("Table of random numbers for drawing geometric shapes in different     colours, sizes and opacities\n");

int rn = 0;
unsigned int seed = (unsigned int)time(NULL);
srand(seed);

int k = 0;
printf("shape#\tRSCE\tx\ty\twidth\theight\tred\tgreen\tblue\tgreen\topacity\n");
while (k < NO_SHAPES){
    printf("%6d", k);
    rn = rand() % SHAPE_RANGE;
    printf( "\t%4d",rn);
    rn = rand() % X_RANGE;
    printf("\t%d",rn);
    rn = rand() % Y_RANGE;
    printf("\t%d",rn);
    rn = rand() % WIDTH_RANGE;
    printf("\t%5d",rn);
    rn = rand() % HEIGHT_RANGE;
    printf("\t%6d",rn);
    rn = rand() % RED_RANGE;
    printf("\t%3d",rn);
    rn = rand() % GREEN_RANGE;
    printf("\t%5d",rn);
    rn = rand() % BLUE_RANGE;
    printf("\t%4d",rn);
    rn = rand() % OPACITY_RANGE;
    printf("\t%.1f\n",rn/100.0);
    k++;
    }

    FILE* ofp = createtxt("myrandom.txt")
    closetxt(ofp);

    return EXIT_SUCCESS;
}

最佳答案

我可能会考虑创建一个 ffprintf()功能:

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

extern int ffprintf(FILE *fp1, FILE *fp2, char const *fmt, ...);

int ffprintf(FILE *fp1, FILE *fp2, char const *fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    int rc1 = vfprintf(fp1, fmt, args);
    va_end(args);
    va_start(args, fmt);
    int rc2 = vfprintf(fp2, fmt, args);
    va_end(args);
    assert(rc1 == rc2);
    return rc1;
}

那么主要代码可以是:

FILE* ofp = createtxt("myrandom.txt")

ffprintf(stdout, ofp, "shape#\tRSCE\tx\ty\twidth\theight\tred\tgreen\tblue\tgreen\topacity\n");
while (k < NO_SHAPES)
{
    ffprintf(stdout, ofp, "%6d", k);
    rn = rand() % SHAPE_RANGE;
    ffprintf(stdout, ofp, "\t%4d", rn);
    ...
}

closetxt(ofp);

如果您不习惯使用可变长度参数列表,您可以编写该函数的更简单版本:

extern int ffprintf(FILE *fp1, FILE *fp2, char const *fmt, int value);

int ffprintf(FILE *fp1, FILE *fp2, char const *fmt, value)
{
    int rc1 = fprintf(fp1, fmt, value);
    int rc2 = vfprintf(fp2, fmt, value);
    assert(rc1 == rc2);
    return rc1;
}

现在你必须写两次标题:

char const header[] =
     "shape#\tRSCE\tx\ty\twidth\theight\tred\tgreen\tblue\tgreen\topacity\n";

fputs(header, stdout);
fputs(header, ofp);

其余大部分可以保持不变,但不透明度( float )以及标题行需要特殊处理。

显然,如果您不喜欢函数名称侵犯函数的标准名称,则可以更改函数名称。如果您采用更简单的方法,则函数名称应更改为类似 ffprint_int() 的名称。因为它只打印一个 int一次。

使用assert()是惰性的,但它确实确保两个打印操作都成功(或都失败)。如果您对此感到担心,请将该断言更改为如下内容:

if (rc2 < rc1)
    rc1 = rc2;

这将返回两个值中较小的一个;如果为 -1(完全失败),则这就是将返回的值。当然,由于我编写的代码忽略了 ffprintf() 的返回值。 ,就像您的代码忽略 printf() 的返回值一样,这是一个基本上不会被注意到的细微差别。

关于c - 如何同时输出到控制台和文本文件以使它们相同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19626615/

相关文章:

c - 在 Linux 中检测 RS-232 com 端口

c - fscanf() 遇到 EOF 后程序崩溃

linux - 读取文本文件的系统调用

c - 这个错误描述在 fread() 中意味着什么

c - 获取段错误

c - 文件操作复制一个 .mp3 文件以创建另一个相同的文件

java - 文本文件行读取器 - java

c# - 写入文本文件

c++ - 在二叉树中,找出有多少祖父只有两个或三个孙子

javascript - Krajee file-input submit files on form 提交