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"写入文件并换行。
//写入文件
#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;

}

 

posted @ 2022-01-24 21:02  chenjian688  阅读(733)  评论(0编辑  收藏  举报