C++下的格式化输入与输出
1. 浮点数介绍
_Float32 a, _Float64 b;
实际上float类型存储数据的间隔不是等间距的,而是在0的附近间距小,在远离0的位置间距大。虽然表示的数范围大,但是超过一定范围内就不准了,精度是有限制的。
float32 确保7位有效数,(包含整数位和小数位,从左向右数,整数部分为0则不计整数的有效位数)
float64 确保16位有效数
剩余部分可能准,也可能不准
2、输入输出流
在编程过程中我们经常需要用到输入输出函数,接下来分别介绍以下几个函数:
2.1. prinf() :
printf("name = %d", 555);
printf("name = %d\n", 555);
printf("name = %.9f\n", 555.0);
printf("name = %s\n", "555"); *注意数据格式要和打印类型相对应,不然会出错,比如%f打印整数,结果总为0
2.2. std::cout
和printf差不多,默认输出6位有效数,也可以控制输出的精度,会根据精度四舍五入打印
#include<iomanip>
using namespace std;
/*
std::setprecision(3) //设置有效位数
std::fixed //设置有效位数位为小数部分长度
*/
cout <<std::fixed <<std::setprecision(3) <<110.00;
//这种控制输出精度的方法,也适用于sstream、fstream等流,可以控制浮点数写入流的小数位数。
2.3.stream流
2.3.1 sstream
#include <sstream>
/**
stringstream通常用来做数值<---->字符串相互转换
使用的是stringstream函数,在c++11当中有定义好的现成的函数取调用,非常方便。
在1、<sstream>中有一个类 istringstream可以把字符串根据空格、tab、换行符分割(元素之间分隔符个数不限),
调用>>,可以输出或者输入流,输出流后,原来stringstream中的就没有这个元素了,所以
可以循环调用输出>>,将元素一个个输出。
**/
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
int main()
{
string str="AA BB CC B 1 123 ";
istringstream stream(str);//声明一个istingstream的对象,并且绑定一个字符串。
string s;
while(stream>>s){
cout<<s<<endl;
}
return 0;
}
/*
方法stringstream,可以看成一个缓冲区,经常用来string<-->int/double转换。
*/
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
int main()
{
stringstream stream;
int n;
string str="1234567";
stream<<str;//向stream中插入str
stream>>n;
//从strea中提取刚才装入的字符串,并将其付给n。并且完成从string 到int的转换。
cout<<"int型数据:"<<n;
return 0;
}
4.2 fstream
#include 是C++的预编译语句,作用是包含对应的文件,在这里是包含C++的STL头文件fstream。
在包含了这个文件后,就可以使用fstream中定义的类及各种成员函数了。
fstream是C++ STL中对文件操作的合集,包含了常用的所有文件操作。在C++中,所有的文件操作,都是以流(stream)的方式进行的,fstream也就是文件流file stream。
最常用的两种操作为:
1、插入器(<<)
向流输出数据。比如说打开了一个文件流fout,那么调用fout<<"Write to file"<<endl;就表示把字符串"Write to file"写入文件并换行。
在包含了这个文件后,就可以使用fstream中定义的类及各种成员函数了。
fstream是C++ STL中对文件操作的合集,包含了常用的所有文件操作。在C++中,所有的文件操作,都是以流(stream)的方式进行的,fstream也就是文件流file stream。
最常用的两种操作为:
1、插入器(<<)
向流输出数据。比如说打开了一个文件流fout,那么调用fout<<"Write to file"<<endl;就表示把字符串"Write to file"写入文件并换行。
//写入文件
#include <fstream>
#include <spdlog/spdlog.h>
#include <iomanip>
using namespace std;
using namespace spdlog;
int main(int argc, char** argv){
string str = "test_fstream.txt";
ofstream write(str, std::ios::trunc | std::ios::out);
if(write.fail()){
warn("no this file");
}
write<<std::fixed << std::setprecision(3)<<1000.0006<<"\t"
<<std::fixed << std::setprecision(0)<<200<<"\t"
<<"heuagtjg\n";
write.close();
return 0;
}
2、析取器(>>)
从流中输入数据。比如说打开了文件流fin,那么定义变量(int double string等)x的情况下,fin>>x;就是从文件中读取一个数据,并存储到x中,实现了读取数据并自动进行类型装换。
//读取文件
#include <fstream>
#include <spdlog/spdlog.h>
#include <iomanip>
#include <vector>
#include <sstream>
using namespace std;
using namespace spdlog;
int main(int argc, char** argv){
string str = "test_fstream.txt";
ifstream read(str);
if(read.fail()){
warn("no this file");
}
double tmp_data;
vector<double> data;
while(read>>tmp_data){ //有流输出才为真
data.push_back(tmp_data);
info("tmp_data: {:.7f}", tmp_data);
tmp_data = 0;
}
read.close();
//上面这种方法是所有数,存入vector一维数组,此时不能知道原始数据的行数和列数。
//可以配合按行读取函数,将每一行存入sstream流中,再将每一行数据存入一维数组中,这样可以获取行数和列数。
string test = "";
vector<vector<double>> MyData;
while (getline(read, test)) //全局函数,隶属于<string>头文件,空行也会被读入,但流数据为空
{
if(test == "") continue; //排除空行
stringstream os_data(test);
double tmp;
vector<double> mydata;
while(os_data >> tmp){
info("into");
info("tmp: {:.7f}", tmp);
mydata.push_back(tmp);
}
MyData.push_back(mydata);
// os_data << std::fixed << std::setprecision(3) << 12.00;
// string xxx = "";
// while (os_data >> xxx)
// {
// /* code */
// }
}
return 0;
}