zoukankan      html  css  js  c++  java
  • C++ 文件读写方案选型

    严格来说, 有 3 种风格.

    1. UNIX 底层读写库
    2. c 语言 stdio 标准库
    3. iostream 流

    一般的工程中, 底层读写库封装程度太低, 需要自己处理缓存和很多通用的异常场景. 不适合.

    网络编程中, 缓存会导致很多负面作用, 可以考虑用底层的读写库.

    1. 格式化输出对比

    1.1 格式化输出的可配置性

    iostream 采用 manipulator 来格式化, 格式化信息写死在代码中, 难以实现可配置. -- 软件工程中绝对的硬伤.

    stdio 采用的 %d %s 等已经发展成一个 DSL, 并在很多语言中通用. http://en.wikipedia.org/wiki/Printf_format_string#Programming_languages_with_printf

    1.2 上下文无关

    iostream 中, 通过改变流的状态来实现格式化输出, 而流的状态是全局的. 需要时刻小心,防止影响了后面的代码.

    stdio 是上下文无关的.

    1.3 缓冲区溢出

    stdio 问题在于, 不是类型安全的, 而且存在缓冲区溢出的安全风险. 正确而安全的做法如下

    #include <stdio.h>
    
    int main()
    {
        const int max = 80;
        char name[max];
    
        char fmt[10];
        sprintf(fmt, "%%%ds", max - 1);
        scanf(fmt, name);
        printf("%s
    ", name);
    }

    1.4 类型安全与 64 位兼容性

    stdio 的标准库, 需要明确知道待输出数据的类型, 并选择合适的 %d, %ld.

    格式化字符串与参数类型不匹配会造成难以发现的 bug.

    如果考虑到同时在 32 和 64 位机器上支持正确打印, %d 的选取更加头疼.

    《The Linux Programming Interface》的作者建议(3.6.2节)先统一转换为 long 类型再用 "%ld" 来打印;对于某些类型仍然需要特殊处理,比如 off_t 的类型可能是 long long。

    http://google-styleguide.googlecode.com/svn/trunk/cppguide.html#64-bit_Portability

    printf 无法像打印 int 那样用 printf 来直接打印 自定义对象。

    1.5 性能

      1. 即使只使用了解释程序的一个功能,也要全部装载。如上面的例子,我们要装载整个包,包括解释浮点数和字符串那部分程序段,无法减少程序的长度。  2. 虽然printf族函数已经优化得很好,但是,它是在运行期间进行解释,如果能在编译期间分析格式字符串里的变量,根据不同的类型调用各自的函数处理,运行会快得多,而且C++编译期间的类型检查会有助于我们发现错误.

    在线 ACM/ICPC 判题网站上,如果一个简单的题目发生超时错误,那么把其中 iostream 的输入输出换成 stdio,有时就能过关。
      3. 对于C++来说,printf不能被扩展是它最大的缺点。我们不能通过重载函数对它进行扩展,因为重载函数要有不同类型的参数,而printf族函数把类型信息隐藏在可变参数表和格式字符串中。

    2. 线程安全

    stdio 的函数是线程安全的,

    而且 C 语言还提供了 flockfile(3)/funlockfile(3) 之类的函数来明确控制 FILE* 的加锁与解锁。

    cout << a << b; 是两次函数调用,相当于 cout.operator<<(a).operator<<(b)。

    两次调用中间可能会被打断进行上下文切换,造成输出内容不连续,插入了其他线程打印的字符。

    3. 内存泄露

  • 相关阅读:
    keil 提示"running with code size limit 32k"
    关于C语言编译出现give arg types警告问题
    windows10添加设备管理器的快捷方式到桌面
    deepin20社区版 安装 STM32CubeIDE 小记
    STM32开发 printf和scanf函数的重定向——修改HAL标准库用printf函数发送数据直接输出
    ardupilot环境配置之eclipse指定jdk版本启动,解决“Version XXXX of the JVM is not ......"报错的问题
    jdk9,10,11,12没有jre安装方法
    C++ 类构造函数 & 析构函数
    STM32 Keil中关于stlink的调试 下载设置
    STM32 SWD下载出现no target connect解决方法
  • 原文地址:https://www.cnblogs.com/misspy/p/4042118.html
Copyright © 2011-2022 走看看