【问题标题】:What are some best practices for file I/O in C?C 中文件 I/O 的一些最佳实践是什么?
【发布时间】:2013-03-14 20:07:39
【问题描述】:

我正在编写一个相当基本的程序供个人使用,但我真的想确保我使用良好的做法,特别是如果我决定以后让它更健壮或什么的时候。

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

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

我是否应该在写入时将其保存在临时目录中,然后在完成后移动它?我应该使用更高级的文件 i/o 库吗?我是不是完全想多了?

【问题讨论】:

  • 对于这么简单的事情,我认为你想多了。如果您是写入文件的唯一进程(或线程),则无需额外工作。
  • 欢迎来到 Stack Overflow。请尽快阅读FAQ。这可能是一个没有准确答案的问题。在大多数情况下,您所做的一切都很好。临时目录可能是矫枉过正。您可能想检查fclose() 是否有效;如果不是,您必须假设该文件未正确创建,并且可能应该将其删除。您可能需要检查每个输出操作;这是理论上正确的方法。显然,你必须检查fopen(),否则你会崩溃。

标签: c file io


【解决方案1】:

我眼中的最佳实践:

  • 检查对 fopen、printf、puts、fprintf、fclose 等的每次调用是否有错误
  • 如果必须使用 getchar,如果可以,请使用 fread
  • 如果必须使用 putchar,如果可以使用 fwrite
  • 避免对输入行长度进行任意限制(可能需要 malloc/realloc)
  • 知道何时需要以二进制模式打开输出文件
  • 使用标准 C,忘记 conio.h :-)
  • 换行符位于行的结尾,而不是某些文本的开头,即它是printf ("hello, world\n"); 而不是"\nHello, world",就像那些被强大的威廉H.误导的人经常写信给应对他们愚蠢的命令外壳。
  • 如果您需要超过 7 位的 ASCII,请选择Unicode(最常见的编码是 UTF-8,它与 ASCII 兼容)。这是您需要学习的最后一种编码。远离代码页和 ISO-8859-*。

【讨论】:

  • 我能问一下为什么你说getcharputchar 是只能在“必须”时使用的函数吗?
  • 基本上它只是对大块 I/O 与逐字符 I/O 的偏好。 {get,put}char() 本身并没有错。如果你重新实现cat,使用字符I/O显然不是最优的。
【解决方案2】:

我是不是完全想多了?

你是。如果任务很简单,不要仅仅因为感觉“更专业”而故意做出复杂的解决方案。当您是初学者时,请注意代码的可读性,这将有助于您和他人的生活。

【讨论】:

    【解决方案3】:

    没关系。默认情况下,I/O 使用 stdio 文件函数完全缓冲,因此您不会在每次调用 fprintf 时都写入文件。事实上,在很多情况下,在您调用 fclose 之前,不会向其写入任何内容。

    检查fopen 的返回、完成后关闭文件等是一种很好的做法。让操作系统和编译器完成他们的工作,使其余部分高效,对于像这样的简单程序。

    【讨论】:

      【解决方案4】:

      如果没有其他程序正在检查~/program/csv/output.csv 的存在以进行进一步处理,那么您正在做的事情就很好。

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

      【讨论】:

        【解决方案5】:

        您可以制作自己的catcpmv 练习程序。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-12-15
          • 1970-01-01
          • 1970-01-01
          • 2011-03-28
          • 1970-01-01
          • 1970-01-01
          • 2011-06-07
          相关资源
          最近更新 更多