我一直在使用 C 和 C++ 工作,当涉及到文件处理时,我感到很困惑。说说我知道的吧。
在 C 中,我们使用函数:
- fopen、fclose、fwrite、fread、ftell、fseek、fprintf、fscanf、feof、fileno、fgets、fputs、fgetc、fputc。
- FILE *fp 文件指针。
- 像 r, w, a 这样的模式
我知道什么时候使用这些功能(希望我没有错过任何重要的事情)。
在 C++ 中,我们使用函数/运算符:
- fstream f
- f.open、f.close、f>>、f<<、f.seekg、f.seekp、f.tellg、f.tellp、f.read、f.write、f.eof。
- 像 ios::in、ios::out、ios::bin 等模式......
那么是否可以(推荐)在C++中使用C兼容的文件操作? 哪个使用更广泛,为什么? 除了这些我还应该注意什么吗?
最佳答案
有时,现有代码期望您需要与之交互,这可能会影响您的选择,但通常情况下,如果 C 版本没有问题,就不会引入 C++ 版本。使固定。改进包括:
RAII 语义,这意味着例如
fstream
在离开作用域时关闭它们管理的文件在发生错误时抛出异常的模态能力,这可以使专注于典型/成功处理的代码更清晰(有关 API 函数和示例,请参阅 http://en.cppreference.com/w/cpp/io/basic_ios/exceptions)
类型安全,这样输入和输出的执行方式是使用涉及的变量类型隐式选择的
- C 风格的 I/O 有可能发生崩溃:例如
int my_int = 32; printf("%s", my_int);
,其中%s
告诉printf
期望一个指向 ASCIIZ 字符缓冲区的指针,但是my_int
出现;首先,参数传递约定可能意味着int
以不同方式传递给const char*
,其次sizeof int
可能不等于sizeof const char*
,最后,即使printf
将32
提取为const char*
充其量 它只会打印从内存地址 32 开始的随机垃圾,直到它碰巧遇到一个 NUL 字符——更有可能的是,进程将缺乏读取部分内存的权限,程序将崩溃。现代 C 编译器有时可以根据提供的参数验证格式字符串,从而降低这种风险。
- C 风格的 I/O 有可能发生崩溃:例如
用户定义类型的可扩展性(即您可以教流如何处理您自己的类)
支持根据实际输入动态调整接收字符串的大小,而 C 函数往往需要在用户代码中硬编码最大缓冲区大小和循环以组合任意大小的输入
流媒体有时也会因为以下原因受到批评:
与
printf
-style 格式字符串相比,格式的冗长,尤其是“io manipulators”设置宽度、精度、基数、填充有时令人困惑的操纵器组合,它们在多个 I/O 操作中保留其设置,而其他操纵器在每次操作后重置
缺少用于 RAII 推送/保存和稍后弹出/恢复操纵器状态的便利类
正如 Ben Voigt 评论和记录的那样缓慢 here
关于c++ - C 与 C++ 文件处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25903590/