• CV学习日志:C语言中文件IO使用要点


    1.prinf(fmt,…)/sprinf(str,fmt,…)/fsprintf(file,fmt,…)

             (1)格式:%[标志][宽度][.精度][长度]<类型>

             (2)宽度:若实际位数大于宽度则按实际位数输出,若小于宽度则用空格或0填充

             (3)精度:对整型若超出则完整输出若不足则高位补0,对浮点型表示最多输出的小数位,对字串表示最多输出的字符数

             (4)标志

                      对齐方式:-表示左对齐输出,而默认是右对齐车联网

                      符号显示:+表示正负数前正负号,空格表示正数前加空格、负数前加负号

                      空位填充:0表示左边有空位则用0填充(但对指定了最大精度的整型失效)

                      进制前缀:#表示八进制前加o、十六进制前加0x

    2.scanf(fmt, …)/sscanf(str,fmt,…)/fscanf(file,…)

             (1)从键盘流/字符流/文件流读数据

             (2)读取时跳过输入流开头的空字符(如space/enter/tab)

             (3)读到空字符(如space/enter/tab)时返回

             (4)scanf输入回车后才能启动读

             (5)成功读时返回读的项数,失败(出错或读到文件尾)返回EOF

    3.fwrite(ptr, size, count, file)/fread(ptr, size, count, file)

             (1)fwrite从ptr写入size*count字节到file、fread从file中读取size*count字节到ptr

             (2)参数ptr尺寸应不小于size*count,否则程序崩溃

             (3)等价地fwrite(ptr,size,count,file)=fwrite(ptr,size*count,1,file)=fwrite(ptr,1,size*count,file)

             (4)等价地fread(ptr,size,count,file)=fread(ptr,size*count,1,file)=fread(ptr,1,size*count,file)

             (5)fread不能跳过空字符(如space/enter/tab),对于文件是由字符文件头和二进制数据段组成的且文件头与数据段由空字符分隔的文件,在读取时要注意读取此空字符(用fget函数即可),否则不能正确地读取数据段。

             以下使用样例,依赖于C++14和Spdlog。

     1 #include <spdlog/spdlog.h>
     2 using namespace std;
     3 
     4 class AboutCIO
     5 {
     6 public:
     7     static void aboutPrintf(int argc = 0, char** argv = 0)
     8     {
     9         //1.
    10         string path = "./text.txt";
    11         vector<int> idxs = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; //C++11 list initialization
    12         vector<float> vals = { 1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f, 9.9f };
    13 
    14         //2.
    15         FILE* file = fopen(path.c_str(), "w"); //write header informations like record numbers for more convenient fscanf if possible
    16         for (int k = 0; k < idxs.size(); ++k) fprintf(file, "index: %-10d	value: %-10.3f
    ", idxs[k], vals[k]);//fscanf stops when meeting null chars: space, enter, tab and so on.
    17         fclose(file);
    18         spdlog::info("{} write to: {}", __FUNCTION__, path);
    19     }
    20     static void aboutScanf(int argc = 0, char** argv = 0)
    21     {
    22         //1.
    23         string path = "./text.txt";
    24         vector<int> idxs;
    25         vector<float> vals;
    26 
    27         //2.
    28         int idx;
    29         float val;
    30         char tmp[50];
    31         FILE* file = fopen(path.c_str(), "r");//read header informations like record numbers first if possible
    32         while (fscanf(file, "%s%d%s%f", tmp, &idx, tmp, &val) != EOF) { idxs.push_back(idx); vals.push_back(val); }
    33         fclose(file);
    34 
    35         //3.
    36         for (int k = 0; k < idxs.size(); ++k) spdlog::info("index: {:<10d}	value: {:<10.3f}", idxs[k], vals[k]);
    37         spdlog::info("{} read from: {}", __FUNCTION__, path);
    38     }
    39 
    40     static void aboutWrite(int argc = 0, char** argv = 0)
    41     {
    42         //1.
    43         string path = "./mat.bin";
    44         vector<int> mat = { 1, 2, 3, 4, 5, 6, 7, 5, 9, 10, 11, 12 };
    45         const char* type = typeid(mat[0]).name();
    46         int rows = 3;
    47         int cols = 4;
    48         int stride = int(sizeof(mat[0])) * 4;
    49 
    50         //2.
    51         FILE* file = fopen(path.c_str(), "w");//it is necessary to use header informations for binary files
    52         fprintf(file, "type: %s
    rows: %d
    cols: %d
    stride: %d
    ", type, rows, cols, stride);//space and enter are necessary for fscanf
    53         fwrite(mat.data(), stride, rows, file);//matrix with discontinous storage also could be writen row by row for less memory
    54         fclose(file);
    55         spdlog::info("{} write to: {}", __FUNCTION__, path);
    56     }
    57     static void aboutRead(int argc = 0, char** argv = 0)
    58     {
    59         //1.
    60         string path = "./mat.bin";
    61         vector<int> mat(1); //type must be determined first
    62 
    63         //2.
    64         char type[10], tmp[50];
    65         int rows, cols, stride;
    66         FILE* file = fopen(path.c_str(), "r");
    67         fscanf(file, "%s%s%s%d%s%d%s%d", tmp, type, tmp, &rows, tmp, &cols, tmp, &stride);
    68         fgetc(file);//fread could not skip null chars
    69         mat.resize(rows * cols); //assume that stride be equal to sizeof(type) * cols
    70         fread(mat.data(), stride, rows, file);
    71         fclose(file);
    72 
    73         //3.
    74         spdlog::info("type: {}
    rows: {}
    cols:{}
    stride: {}", type, rows, cols, stride);
    75         for (int i = 0, io = 0; i < rows; ++i, io += cols)
    76         {
    77             string str = fmt::format("row{}: ", i);
    78             for (int j = 0, jo = io; j < cols; ++j, ++jo) str += fmt::format("{:<10d}", mat[jo]);
    79             spdlog::info(str);
    80         }
    81         spdlog::info("{} read from: {}", __FUNCTION__, path);
    82     }
    83 };
    84 
    85 int main(int argc, char** argv)
    86 {
    87     spdlog::set_pattern("%v");
    88     AboutCIO::aboutPrintf(argc, argv);
    89     AboutCIO::aboutScanf(argc, argv);
    90     spdlog::info("");
    91     AboutCIO::aboutWrite(argc, argv);
    92     AboutCIO::aboutRead(argc, argv);
    93     return 0;
    94 }
    View Code
  • 相关阅读:
    前端 fetch 通信
    编写高质量的JavaScript代码(一)
    Redis学习笔记1-Redis的介绍和认识
    gitignore不起作用解决的方法
    【我的面经】说说简历的细节——软件开发岗位
    菜鸟的mongoDB学习---(七)MongoDB 备份(mongodump)与恢复(mongorerstore)
    HDU 4927 Series 1
    树状数组求第K小值 (spoj227 Ordering the Soldiers &amp;&amp; hdu2852 KiKi&#39;s K-Number)
    git和SVN的差别
    KVM-Introduce
  • 原文地址:https://www.cnblogs.com/dzyBK/p/13843618.html
Copyright © 2020-2023  润新知