C语言中文件输入输出的最佳实践有哪些?

6

我正在为个人使用编写一个相当基本的程序,但我真的希望确保我使用良好的实践方法,特别是如果我决定以后将其变得更加健壮。

就所有目的而言,该程序接受一些输入文件作为参数,使用fopen()打开它们并读取文件,对该信息进行处理,然后将输出保存为子文件夹中的几个不同文件。例如,如果程序在~/program中,则输出文件将保存在~/program/csv/中。

我直接输出到文件,例如output = fopen("./csv/output.csv", "w");,在循环中使用fprintf(output,"%f,%f", data1, data2);进行打印,然后使用fclose(output);关闭,我觉得这是不好的实践。

在写入时,我应该将其保存在临时目录中,然后在完成时将其移动吗?我应该使用更高级的文件I/O库吗?还是我完全在过度思考?


2
对于这么简单的事情,我认为你想得太多了。如果你是唯一写入文件的进程(或线程),那么就不需要额外的工作了。 - Randy Howard
1
欢迎来到 Stack Overflow。请在不久的将来阅读[FAQ]。这可能是一个没有精确答案的问题。总体而言,您所做的事情还不错。临时目录可能有点杀鸡焉用牛刀了。您可能要检查 fclose() 是否起作用;如果不起作用,则必须假设文件未被正确创建,并应该将其删除。您可能要检查每个输出操作;这是理论上正确的方式。显然,你必须检查fopen(),否则程序会崩溃。 - Jonathan Leffler
5个回答

9

在我看来,最佳实践如下:

  • 检查每个对 fopen、printf、puts、fprintf、fclose 等的调用是否有错误
  • 如果必须使用,就使用 getchar;如果可以使用,就使用 fread
  • 如果必须使用,就使用 putchar;如果可以使用,就使用 fwrite
  • 避免对输入行长度设置任意限制(可能需要使用 malloc/realloc)
  • 知道何时需要以二进制模式打开输出文件
  • 使用标准的 C 语言,忘记 conio.h :-)
  • 换行符应该在一行的结尾,而不是一些文本的开头。例如,应该是 printf("hello, world\n"); 而不是像那些被强大的威廉·H.误导的人们所写的 "\nHello, world" 以应对其命令行解释器的愚蠢。首先输出换行符会破坏行缓冲 I/O。
  • 如果需要超过 7 位 ASCII 字符,则选择 Unicode(最常见的编码是与 ASCII 兼容的 UTF-8)。这是你将学习到的最后一个编码。远离代码页和 ISO-8859-*。

我可以问一下为什么你说getcharputchar是只有在必要时才使用的函数吗? - Ricky Stewart
基本上,这只是对大块I/O与逐字符I/O的偏好。{get,put}char()并没有本质上的问题。如果您重新实现“cat”,使用字符I/O显然是次优的。 - Jens

4

我是不是想得太多了?

是的,你想得太多了。如果任务很简单,不要故意制造复杂的解决方案只是为了感觉更加“专业”。作为初学者,应该注重代码的可读性,这将有助于你和其他人的工作。


1

没问题。I/O 默认情况下使用 stdio 文件函数进行完全缓冲,因此您不会在每次调用 fprintf 时都写入文件。实际上,在许多情况下,直到调用 fclose 才会写入。

检查 fopen 的返回值,关闭文件等是一个好的习惯。对于像这样的简单程序,让操作系统和编译器发挥其效率即可。


0

如果没有其他程序检查进一步处理的~/program/csv/output.csv的存在,则您所做的就很好。

否则,您可以考虑写入通过调用stdio.h中的tmpfile或某个类似库调用获得的FILE *,并在完成后将文件复制到最终目标。您还可以放置锁定文件output.csv.lck,并在完成后删除该文件,但这取决于您能否修改其他程序的行为。


0
你可以自己编写 catcpmv 程序进行练习。

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