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\tvalue: %-10.3f\n", 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}\tvalue: {:<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\nrows: %d\ncols: %d\nstride: %d\n", 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: {}\nrows: {}\ncols:{}\nstride: {}", 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 }