ZetCode

C fprintf 函数

最后修改日期:2025 年 4 月 6 日

格式化输出在 C 编程中对于清晰一致地显示数据至关重要。fprintf 函数为控制台和文件输出提供了强大的格式化功能。本教程将深入探讨 fprintf,涵盖其语法、格式说明符和实际应用。您将学习创建专业的输出,同时理解安全注意事项和稳健代码的最佳实践。

fprintf 是什么?

fprintf 函数将格式化数据写入指定的输出流,通常是文件或 stdout。它类似于 printf,但功能更强大,接受文件指针作为第一个参数。该函数使用 %d%f%s 等格式说明符来控制输出格式。写入文件时务必检查错误,因为磁盘空间或权限问题可能导致失败。出于安全考虑,请尽可能优先使用 fprintf 而非不安全的函数,如 sprintf

基本 fprintf 到标准输出

此示例演示了如何使用 fprintf 将格式化输出写入控制台 (stdout)。

basic_fprintf.c
#include <stdio.h>

int main() {
    int age = 25;
    float height = 1.75f;
    char name[] = "Alice";

    // Write formatted output to stdout
    fprintf(stdout, "Name: %s\nAge: %d\nHeight: %.2f meters\n", 
            name, age, height);

    return 0;
}

在这里,fprintf 将格式化文本发送到 stdout,就像 printf 一样。格式字符串包含占位符:%s 用于字符串,%d 用于整数,%.2f 用于保留两位小数的浮点数。变量 nameageheight 提供值。当您希望控制台和文件写入具有一致的输出格式时,此方法非常有用。

将格式化数据写入文件

了解如何使用 fprintf 将结构化数据写入文本文件。

file_output.c
#include <stdio.h>

int main() {
    FILE *fp = fopen("user_data.txt", "w");
    if (fp == NULL) {
        perror("Error opening file");
        return 1;
    }

    char username[] = "johndoe";
    int logins = 42;
    double balance = 1250.75;

    // Write formatted data to file
    fprintf(fp, "User: %s\nLogins: %d\nBalance: $%.2f\n", 
            username, logins, balance);

    fclose(fp);
    return 0;
}

此示例以写入模式 (“w”) 打开 "user_data.txt",如果不存在则创建。fprintf 函数写入三个带有描述性标签的数据。请注意 %.2f 中的精度控制,用于将余额格式化为两位小数。务必检查文件是否成功打开,并在完成后关闭它。生成的文件将包含格式整齐、人类可读的数据。

将格式化数据追加到文件

查看如何将新格式化的记录添加到现有文件中而不覆盖。

append_data.c
#include <stdio.h>
#include <time.h>

int main() {
    FILE *fp = fopen("log.txt", "a");  // Append mode
    if (fp == NULL) {
        perror("Error opening log file");
        return 1;
    }

    time_t now;
    time(&now);
    
    // Append timestamped log entry
    fprintf(fp, "[%s] User action: Login attempt\n", ctime(&now));
    
    fclose(fp);
    return 0;
}

以追加模式 (“a”) 打开文件可确保新内容添加到末尾。该示例使用 timectime 为每个日志条目添加时间戳。fprintf 将其格式化为结构化日志行。重复运行会添加新条目,而不会影响现有内容。这种模式非常适合日志系统,因为它们需要保留历史记录。

fprintf 的错误处理

在对关键操作使用 fprintf 时实现稳健的错误检查。

error_handling.c
#include <stdio.h>
#include <errno.h>

int main() {
    FILE *fp = fopen("important.dat", "w");
    if (fp == NULL) {
        perror("Failed to open file");
        return 1;
    }

    int items_written = fprintf(fp, "Critical data: %d\n", 42);
    
    if (items_written < 0) {
        perror("Write operation failed");
        fclose(fp);
        return 1;
    }

    if (fclose(fp) == EOF) {
        perror("Failed to close file");
        return 1;
    }

    printf("Successfully wrote %d items\n", items_written);
    return 0;
}

此示例演示了全面的错误处理。fprintf 返回写入的字符数,或在失败时返回负值。我们检查此返回值以检测写入错误。fclose 操作也需要检查,因为缓冲写入可能在关闭期间失败。这种防御性编程可防止生产环境中出现静默失败。处理文件时,始终验证关键的 I/O 操作。

格式化复杂数据结构

使用 fprintf 将结构化数据序列化以进行存储或日志记录。

complex_data.c
#include <stdio.h>

typedef struct {
    char id[10];
    float price;
    int quantity;
} Product;

int main() {
    FILE *fp = fopen("inventory.csv", "w");
    if (fp == NULL) {
        perror("Cannot create inventory file");
        return 1;
    }

    Product items[3] = {
        {"A100", 19.99f, 50},
        {"B200", 29.50f, 25},
        {"C300", 9.95f, 100}
    };

    // Write CSV header
    fprintf(fp, "ID,Price,Quantity\n");
    
    // Write each product as a CSV line
    for (int i = 0; i < 3; i++) {
        fprintf(fp, "%s,%.2f,%d\n", 
                items[i].id, items[i].price, items[i].quantity);
    }

    fclose(fp);
    return 0;
}

此示例从产品结构数组创建 CSV 文件。第一个 fprintf 写入列标题,而循环以一致的格式写入每个产品的。请注意使用 %.2f 来标准化价格格式。生成的文件可以轻松导入到电子表格或其他系统中。此技术非常适合以标准格式导出结构化数据。

使用 fprintf 的最佳实践

来源

C fprintf 文档

本教程探索了多功能的 fprintf 函数,从基本的控制台输出到复杂的文件格式化。掌握这些技术可以使您在 C 程序中创建专业、可靠的输出,同时保持安全性和稳健性。

作者

我叫 Jan Bodnar,是一名敬业的程序员,对编码充满热情。自 2007 年以来,我通过 1400 多篇文章和 8 本电子书分享我的专业知识。凭借十多年的教学经验,我致力于让编程变得易于理解且引人入胜。

列表 C 标准库