C fprintf 函数
最后修改日期:2025 年 4 月 6 日
格式化输出在 C 编程中对于清晰一致地显示数据至关重要。fprintf
函数为控制台和文件输出提供了强大的格式化功能。本教程将深入探讨 fprintf
,涵盖其语法、格式说明符和实际应用。您将学习创建专业的输出,同时理解安全注意事项和稳健代码的最佳实践。
fprintf 是什么?
fprintf
函数将格式化数据写入指定的输出流,通常是文件或 stdout
。它类似于 printf
,但功能更强大,接受文件指针作为第一个参数。该函数使用 %d
、%f
和 %s
等格式说明符来控制输出格式。写入文件时务必检查错误,因为磁盘空间或权限问题可能导致失败。出于安全考虑,请尽可能优先使用 fprintf
而非不安全的函数,如 sprintf
。
基本 fprintf 到标准输出
此示例演示了如何使用 fprintf
将格式化输出写入控制台 (stdout)。
#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
用于保留两位小数的浮点数。变量 name
、age
和 height
提供值。当您希望控制台和文件写入具有一致的输出格式时,此方法非常有用。
将格式化数据写入文件
了解如何使用 fprintf
将结构化数据写入文本文件。
#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
中的精度控制,用于将余额格式化为两位小数。务必检查文件是否成功打开,并在完成后关闭它。生成的文件将包含格式整齐、人类可读的数据。
将格式化数据追加到文件
查看如何将新格式化的记录添加到现有文件中而不覆盖。
#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”) 打开文件可确保新内容添加到末尾。该示例使用 time
和 ctime
为每个日志条目添加时间戳。fprintf
将其格式化为结构化日志行。重复运行会添加新条目,而不会影响现有内容。这种模式非常适合日志系统,因为它们需要保留历史记录。
fprintf 的错误处理
在对关键操作使用 fprintf
时实现稳健的错误检查。
#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
将结构化数据序列化以进行存储或日志记录。
#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 的最佳实践
- 验证文件指针:在写入之前,务必检查文件是否成功打开。
- 检查返回值:验证
fprintf
的返回值以捕获写入错误。 - 使用精确的格式说明符:使用宽度和精度控制输出(例如,
%8.2f
)。 - 优先使用安全替代方案:对于用户提供的格式字符串,请使用
fprintf
而非易受攻击的函数。 - 正确关闭文件:确保文件已关闭以刷新缓冲区并释放资源。
来源
本教程探索了多功能的 fprintf
函数,从基本的控制台输出到复杂的文件格式化。掌握这些技术可以使您在 C 程序中创建专业、可靠的输出,同时保持安全性和稳健性。
作者
列表 C 标准库。