Qt&C++ Technical Analysis 3 - IOStream

iostream


scanf/printf

Several common input and output stream functions

  • scanfReceive input data from keyboard
  • printfOutput data to the screen
  • fscanfimport data from file
  • fprintfoutput data to file
  • sscanfread data from memory block
  • sprintfOutput data to a memory block.

The C language input and output method has these disadvantages:
the error of the scanf/printf function group parameters cannot be checked at the compilation stage; the interface of the scanf/printf function group cannot be extended to handle new data types; the execution speed of the scanf/printf function group is slow ; The space occupied by the scanf/printf function group cannot be optimized.


iostream overall architecture

iostream includes the following three levels
insert image description here

Input and output characteristics

  • Both output and input operations are processed through a buffer
  • When outputting, the data is written to the buffer first, and the data in it will not be actually written to the external device until the buffer is full
  • Even if only one character is entered, it must go through the buffer

Stream related classes

iostream overall architecture diagram
insert image description here

charTIndicates the type of characters in the stream Template
parameter traitsIndicates the characteristics of the character
Template parameter allocatorIndicates the heap manager, the default value of this parameter is the heap manager of the system


The class template basic_iosis responsible for managing stream buffers. It contains a pointer to the stream buffer. It also contains a status message to record the completeness of the data in the stream buffer.

The class template basic_istreamand basic_ostreamare responsible for the input and output of data respectively
basic_iostream. By inheriting these two class templates, both input and output can be processed.

The class template basic_istringstreamreads data from a string object of type basic_string , and
the class template basic_ostringstreamoutputs data to a string object of this type


stream buffer

A buffer pointer in a basic_ios derived class will point to an object of basic_streambuforbasic_filebuf

The abstract type basic_streambuf does not contain any information about external devices

The class template basic_filebuf writes the data in the output buffer to the file, or reads the data in the file to the input buffer


Overall structure after template specialization

charTiostream specializes all to char, and all traitstochar_traits< char>

charTiostream also specializes all as wchar_t, and all traitsaschar_traits<wchar_t >


file stream

basic_ifstreamAnd basic_ofstreamare responsible for the input and output of the file respectively, and
basic_fstreamcan perform bidirectional operations on the input and output of the file


file stream object creation

fstreamCode example: Create a file stream object fs and write data at the end of the file "test.txt"

ios_base6 constants are defined in

  • in means to read a file
  • out means write a file
  • app means write only at the end of a file
  • trunc means to clear the contents of the file
  • binary means to access a file in binary mode
  • ate (short for at end) indicates that the initial read/write position is the end of the file.
fstream fs("test.txt", ios_base::out | ios_base::app)

When reading a file (in mode), it is required that the file must exist;
when writing a file (out mode), the specified file may not exist, and the system will create a new one;


Common file stream operations

Generally, you can directly use <<or >>to perform input and output operations
The following code shows the process of reading and writing files using fstream

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main()
{
    
    
    // 打开文件,以输入、输出和追加的方式打开
    fstream fs("data\\test.txt", ios_base::in | ios_base::out | ios_base::app);

    // 检查文件是否成功打开,如果没有成功打开则输出错误信息并退出程序
    if (!fs) {
    
    
        cerr << "cannot open test.txt";
        exit(-1);
    }

    // 向文件中写入字符串 "hello, world\n"
    fs << "hello, world\n";

    // 将文件读写位置重新定位到文件开头
    fs.seekg(0);

    // 定义字符串变量 s,从文件中读取一个单词并存储到字符串 s 中
    string s;
    fs >> s;

    // 输出字符串 s
    cout << s;
}

Commonly used basic_istreamto getline()get the text content of a whole line


Output Format Settings

hex、oct、decSet the output number system to hexadecimal, octal and default decimal respectively
cout << hex << 20;

setw, stream operator, sets the output width of the next data
cout << swtw(4) << 3;

setprecision(m) will set the position of the decimal point and the digits following it to occupy m characters

The boolalpha stream operator can make bool type data output in the form of true and false instead of 1 and 0

left stream operator, the result is left-aligned


file stream status

C++ stream provides the following member functions to return the state information of a stream

  1. eof(). This function returns true if the input stream has reached the end.
  2. bad(). If the user tries to perform an illegal operation on a stream object, such as moving the file pointer to a place after the end of the file, this function returns true, indicating that the stream object is destroyed.
  3. fail(). This function returns true if an operation applied to the stream was unsuccessful, such as an input stream object expecting to read an integer but the actual input data was a string.
  4. good(). When none of the above conditions occurs, the function returns true.

Stream users can actively analyze the data in the stream and call member functions setstate()to set the status information of the stream

char ch;
if ((ch = ifs.get()) != '<' )
    is.setstate( ios_base::failbit );

string stream

Introduces the process of class template basic_stringstreamreading and outputting to a basic_string object


String stream internal buffer

The stream buffer pointer of the stringstream object points to a stringbuff object, which manages an internal character buffer

The internal character buffer has two pointers: a read operation moves back the "read pointer", and a write operation moves back the "write pointer"


string stream using

// istringstream使用
int i;
if (istringstream(argv[1]) >> i)

// ostringstream使用
struct date {
    
    
    int day,month,year;
} today = {
    
    9,3,2011};
ostringstream ostr;
ostr << today.month << '-' << today.day <<'-' << today.year;if (ostr)
    cout<<ostr.str();

stream buffer

Multiple stream objects can share a stream buffer

#include <iostream>
#include <fstream>
using namespace std;
int main()
{
    
    
    ofstream dec_stream( "demo.txt" );
    ostream  hex_stream( dec_stream.rdbuf() );
    hex_stream << hex << showbase;
    int a[4] = {
    
    12, 34, 56, 78};
    for (int i=1; i<4; i++){
    
    
            dec_stream << a[i];
            hex_stream << "[" << a[i] << "] ";}
    return 0;
}

Stream buffers can perform copy operations

#include <fstream>
#include <sstream>
#include <iostream>
using namespace std;

int main()
{
    
    
    // 打开红楼梦文本文件
    ifstream fs("hong_lou_meng.txt");

    // 将文件内容读取到stringstream对象中
    stringstream ss;
    ss << fs.rdbuf();   // ①

    // 将stringstream对象中的内容转为字符串类型
    string str = ss.str();      // ②

    // 查找字符串 "黛玉" 最后一次出现的位置
    string::size_type pos = str.rfind("黛玉");

    // 将stringstream对象的读写位置定位到 "黛玉" 最后一次出现的位置
    ss.seekg(pos);

    // 读取一行字符串,即 "黛玉" 最后一次出现的那句话
    string one_line;
    getline(ss, one_line);

    // 输出 "黛玉" 最后一次出现的那句话
    cout << one_line << endl;

    return 0;
}

user-defined I/O

By defining a class, attaching two friend functions, and using ostreamand instream, you can implement custom IO

#include <iostream> //包含输入输出流库
using namespace std; //使用标准命名空间

class CPoint {
    
     //定义CPoint类
public:
    CPoint(double p_x=0, double p_y=0) {
    
    x=p_x;  y=p_y;}; //构造函数
    friend ostream& operator << (ostream&, const CPoint&); //输出运算符重载函数的友元声明
    friend istream& operator >> (istream&, CPoint&); //输入运算符重载函数的友元声明
private:
    double x,y; //CPoint对象的x和y坐标
};

ostream& operator <<( ostream& os, const CPoint& point ) //输出运算符重载函数的实现
{
    
    
    os << "<" << point.x << "," << point.y << ">"; //输出CPoint对象的坐标
    return os; //返回输出流对象
}

istream& operator >>(istream& is, CPoint& point) //输入运算符重载函数的实现
{
    
    
    char ch;
    is >> ch;
    if ( ch!='<'){
    
      //如果输入不是以 '<' 开始,则输入失败
            is.setstate( ios_base::failbit ); //设置输入流的状态为失败
            return is; //返回输入流对象
    }
    is >> point.x >> ch >> point.y >> ch; //输入CPoint对象的坐标
}

int main() //主函数
{
    
    
    CPoint p; //定义一个CPoint对象p
    while ( cin>> p ) //从标准输入流中读取CPoint对象,如果读取成功则进入循环
            cout << p << endl; //输出CPoint对象p,然后换行
}

Guess you like

Origin blog.csdn.net/delete_you/article/details/132003113