Summary of knowledge points in Chapter 7 (Input and Output Streams) of C++ Object-Oriented Programming (2nd Edition)

C++ object-oriented programming

参考书目:《C++面向对象程序设计》—— 谭浩强 《C++程序设计:思想与方法》—— 翁惠玉



1. Standard input stream

       In C++, input and output are done through streams. The output operation of C++ converts the state of an object into a sequence of characters and outputs it somewhere. The input operation receives a sequence of characters from somewhere and then converts it into the format required by the state of an object.
       The place where the output data is received and stored is called the target, and the place where the input data comes from is called the source. Input and output operations can be regarded as the flow of character sequences between the source, target and object. The class system that performs input and output operations is called a stream class, and the system that provides stream class implementation is called a stream class library.

Insert image description here

注:此图是简化的流类库的基本类等级图,而不是直接的继承关系图。其实它们都是模板类,箭头表示的是类等级关系。
这个等级关系在头文件iostream.h中说明。在图中,ios类中一个指针成员指向streambuf类的对象。Streambuf类管理流的缓冲区。由于数据隐蔽和封装的需要,普通用户只使用ios、istream和ostream类提供的公有接口,完成流的提取和插入操作。
ios类是istream类和ostream类的虚基类,提供对流的格式化I/O操作和错误处理的成员处理的成员函数。从ios类公有派生istream类和ostream类分别提供对流进行提取和插入操作的成员函数,而iostream类通过组合istream类和ostream类支持对一个流进行双向操作,它并没有提供新成员函数。
iostream中预定义四个流对象,它们分别是cin、cout、cerr、clog。事实上可以将cin视为istream的一个对象,而cout视为ostream的一个对象。流是一个抽象的概念,当实际进行I/O操作时,必须将流和一个具体的物理设备连接起来。

       The devices connected to the four streams predefined by the C++ stream class library are as shown in the table:

flow equipment
cin standard input device
cout standard output device
cerr Standard error output device (unbuffered mode)
clog Standard error output device (buffered mode)

       Header files related to the iostream class library: The declarations of different classes in the iostream class library are placed in different header files. When the user uses the #include command to include the required header files in the program, it is equivalent to declaring all the required header files in the program. required class.

  • iostream input and output stream operations

  • fstream manages file I/O operations

  • strstream character stream I/O operations

  • stdiostream Mixing C and C++

  • iomanip uses formatted I/O operations

    注:已在iostream头文件中重载了>> 和<<运算符。用于标准类型数据的输入和输出。
    

2. Standard output stream

1. Use control characters to set the data base in the output stream

       The ostream class defines three stream objects: cout, cerr, and clog.

  1. The cout stream object
    cout stream opens a buffer in memory to store the data in the stream. When endl is encountered, all data in the stream is immediately output, then a newline character is inserted and the buffer is cleared.
  2. cerr stream object
    The cerr stream object is the standard error stream. It outputs information about the error to the standard error device.

Example: Write a program to input the values ​​​​of a, b, and c from the keyboard to solve the quadratic equation ax2+bx+c=0. If a=0 or the value of the discriminant b2-4ac<0, an error message is output.

int main()
{
    
    
	float  a, b, c, disc;
	cout << "请输入 a,b,c:";
	cin >> a >> b >> c;
	if (a == 0)
		cerr << "a 等于0,错误!" << endl;
	else if ((disc = b * b - 4 * a*c) < 0)
		cerr << "判别式b*b-4*a*c<0"<<endl;
	else
		{
    
    
			cout << "x1=" << (-b + sqrt(disc)) / (2 * a) << endl;
			cout << "x2=" << (-b - sqrt(disc)) / (2 * a) << endl;
		}
	return 0;
}

Insert image description here

  1. clog stream object
    The clog stream object is also a standard error stream. The difference between it and cerr is that cerr directly outputs error information to the display without going through the buffer. Clog stores the error information in the buffer and sends it to the display when the buffer is full or endl is encountered. Output error message.
    Insert image description here

Example: Use control characters to control the output format.

#include <iostream>
#include <iomanip>
#include<string>
using namespace std;
int main()
{
    
    
	int a;
	cout << "input a:";
	cin >> a;
	cout << "dec:" << dec << a << endl;
	cout << "hex:" << hex << a << endl;
	cout << "oct:" << setbase(8) << a << endl;
	char *pt = (char *)"China";
	cout << setw(10) << pt << endl;
	cout << setfill('*') << setw(10) << pt << endl;
	double pi = 22.0 / 7.0; cout << setiosflags(ios::scientific) << setprecision(8);
	cout << "pi=" << pi << endl;

	cout << "pi=" << setprecision(4) << pi << endl;
	cout << "pi=" << setiosflags(ios::fixed) << pi << endl;
	return 0;
}

Insert image description here

2. Use the stream member function to set the data base in the output stream

       Common member functions used to control output format are shown in Table 7.4:
Insert image description here
       stream member function setf and control symbol setiosflags. The parameters in brackets are format flags, which are defined in the ios class as enumeration values. Therefore, when referencing these format flags, start with ios::. The format flags are listed in Table 7.5:
Insert image description here

Example: Use flow control member function to output data.

int main()
{
    
    
	int a = 21;
	cout.setf(ios::showbase);
	cout << "dec:" << a << endl;
	cout.unsetf(ios::dec);
	cout.setf(ios::hex);
	cout << "hex:" << a << endl;
	cout.unsetf(ios::hex);
	cout.setf(ios::oct);
	cout << "oct:" << a << endl;
	char *pt =(char *) "China";
	cout.width(10);
	cout << pt << endl;
	cout.width(10);
	cout.fill('*');
	cout << pt << endl;
	double pi = 22.0 / 7.0;
	cout.setf(ios::scientific);
	cout << "pi=";
	cout.width(14);
	cout << pi << endl;
	cout.unsetf(ios::scientific);
	cout.setf(ios::fixed);
	cout.width(12);
	cout.setf(ios::showpos);
	cout.setf(ios::internal);
	cout.precision(6);
	cout << pi << endl;
	return 0;
}

Insert image description here

3. Stream objects

1.cin flow

       cin is an object of the istream class that reads data from the standard input device. Stream extraction operator >> usually skips characters such as spaces, tab keys, newlines, etc. in the stream when extracting data from the stream. Only the data entered when the Enter key is entered enters the keyboard buffer, forming an input stream from which the extraction operator can extract data.
       When an invalid character (inconsistent with the variable data type) or the end of file is encountered, the input stream cin is in an error state, and all operations on the cin stream are terminated. When there is an error in the input stream, the value of cin is false, so you can judge whether the stream object is in a normal state based on the value of cin.

Example: Test the value of cin and determine the status of the stream object.

int main()
{
    
    
	float grade;
	cout << "enter grade:";
	while (cin >> grade)
	{
    
    
		if (grade >= 85)
			cout << grade << " GOOD!" << endl;
		if (grade < 85 && grade >= 60)
			cout << grade << " Just so so!" << endl;
		if (grade < 60)
			cout << grade << " fail!" << endl;
		    cout << "enter grade:";
	}
	cout << "The end." << endl;
	return 0;
}

Insert image description here

2. Stream member function for input characters

  1. Use the get function to read a character
    format:
    the type of the cin.get() function is character, and the function of the function is to extract a character from the input stream and return it as a function value. If the end-of-file character EOF is encountered in the stream, -1 is returned.
int main()
{
    
    
	char c;
	cout << "enter a sentence:" << endl;
	while ((c = cin.get()) != EOF)
		cout.put(c);
	return 0;
}
  1. The format of the get function with one parameter
    : cin.get (character variable)
    extracts a character from the input stream and assigns it to the character variable. If the end-of-file character is encountered, the extraction ends. Enter the Enter followed by the end of file character.
int main()
{
    
    
	char c;
	cout << "enter a sentence:" << endl;
	while (cin.get(c)) {
    
     cout.put(c); }
	cout << "end" << endl;
	return 0;
}
  1. The format of the get function with three parameters
    : cin.get (character pointer, n, terminating character)
    n is related to the number of characters extracted. The function sequentially extracts up to n-1 characters from the keyboard buffer and puts them sequentially into the character array pointed to by the character pointer. If a termination character is encountered during the extraction process, the extraction will be terminated regardless of whether the specified number of characters is met.
void main()
{
    
    
	char ch[20];
	cout << "enter a sentence:" << endl;
	cin.get(ch, 10, '\n');
	cout << ch << endl;
}
  1. Use the member function getline to read a line of characters.
    Format: cin.getline (character pointer, n, terminating character).
    The function function is similar to the get function with three parameters.
    The similarities and differences between cin.get and cin.getline with three parameters:
    The same thing is that they do not ignore whitespace characters encountered during the extraction process, and stop extraction when a termination character is encountered.
    The difference is that when stopping extraction, cin.getline will move the pointer to the adjacent bytes after the termination character, but the cin.get function with three parameters will not.
int main()
{
    
    
	char ch[20];
	char c1;
	cout << "输入一句话:" << endl;
	cin >> ch;
	cout << "第一次 cin 提取的字符串是:" << ch << endl;
	c1 = cin.get();
	cout << "第二次 cin.get() 提取的字符串是:" << c1 << endl;
	cin.get(c1);
	cout << "第三次 cin.get(c1) 提取的字符串是:" << c1 << endl;
	cin.get(ch, 20, '/');
	cout << "第四次 cin.get( ch, 20, '/') 提取的字符串是:" << ch << endl;
	cin.getline(ch, 20, '/');
	cout << "第五次 cin.getline (ch,20,'/')提取的字符串是:" << ch << endl;
	cin.getline(ch, 20, '/');
	cout << "第六次 cin.getline (ch,20,'/')提取的字符串是:" << ch << endl;
	return 0;
}

Insert image description here

注:cin和cin.getline都具有从键盘缓冲区按指针所指提取字符串的功能。它们有以下区别:
1.cin忽略起始的空白字符;而cin.getline不忽略起始的空白字符。
2.cin当提取到非空白字符后,遇到空白字符时就终止提取,指针就停留在空白字符处;而cin.getline是提取到规定的终止字符或规定的字符个数后终止提取,指针停留在提取的最后一个字符后面相邻的字节。
3.通过对>> 的重载,cin可以提取其他类型的数据;而cin.getline只能输入字符串。

3. Other functions of istream class

       The eof() function
       is true when the input buffer pointer encounters the end-of-file character, otherwise it is false. Use ctrl+z to enter the end-of-file character from the keyboard.

Example: Enter a string from the keyboard, use the end of file character as the end mark, and output non-space characters one by one.

void main()
{
    
    
	char c;
	while (!cin.eof())
		if ((c = cin.get()) != '  ')
			//cout.put(c);
			cout << c;
}

4. File operations and file streams

1. The concept of files

       A file refers to a collection of data stored on a storage medium. The operating system abstracts the relevant data on the storage medium into files, names them with identifiers, and manages the files by the file system. As long as the user indicates the file name, the operating system can access the file information by name. According to the representation of data in the file, files are divided into ASCII files and binary files. ASCII files are text files, with each byte representing a character. Binary files store the data and instructions in the memory on the disk according to their format in the memory.
       Character information is also stored in the form of ASCII code in the memory, so the form of characters in the ASCII code file is the same as that in the binary file. For numerical data, the two are not the same. For example, a decimal integer 100000 uses four bytes when represented in binary; while it uses six bytes when represented in ASCII code.
Insert image description here

2. File stream class and file stream object

       A file stream is a data stream that uses external files as input and output objects. The output file stream is the data flow from the memory to the external storage file, and the input file stream is the data flow from the external storage file to the memory. In order to make up for the speed difference between accessing memory and accessing external memory, each file stream has a memory buffer.
       Several file classes are defined in the C++ I/O class library, which are specifically used for file input and output operations.
Insert image description here
       From the figure, we can see that C++ derives three file stream classes from the standard input and output stream classes.

  • The ifstream class supports input from disk files.
  • The ofstream class supports output to disk files.
  • The fstream class supports output and output to disk files.

       To input and output files, you must define a file stream class object and use the object to call the member functions of the class to operate on the file.

3. Opening and closing files

  1. Opening a disk file
    There are two ways to open a file:
    (1) Create a file stream object and use the object to call the class member function open.
    The general form of calling member functions: file stream object.open (file name, input and output mode);
    example: ofstream outfile;
    outfile.open(“f1.txt”, ios::out);
    Insert image description here
    (2) Defining the file stream object When specifying parameters,
    the general form of calling a member function is: file stream class object (file name, input and output mode);
    example: ofstream outfile (“f1.txt”, ios::out);
  2. Closing the disk file
    After the file is used, the file must be closed, which is implemented by calling the file closing member function using the file stream object.
    Format: File stream object.close();
    Function: Disassociate the file stream object from the disk file.

4. Operation on ASCII code files

       ASCII code files are also text files, and each byte in the file stores one character. Operations on ASCII code files include writing characters to the file and reading characters from the file.
       There are two methods for reading and writing ASCII code files: the file stream object and extraction and insertion operators, and using the file stream object to call the member functions put, get, and getline of the class.

Example: Define an integer array with ten elements, enter ten integers from the keyboard, put them into the array, and use the insertion operator to write them to the f1.txt file in the current directory.

#include <iostream>
#include <iomanip>
#include<fstream>
using namespace std;
int main()
{
    
    
	int a[10];
	ofstream outfile("f1.txt");
	if (!outfile)
	{
    
    
		cerr << "open error!" << endl;
		exit(1);
	}
	cout << "enter 10 integer numbers:" << endl;
	for (int i = 0; i < 10; i++)
	{
    
    
		cin >> a[i];
		outfile << a[i] << " ";
	}
	outfile.close();
	return 0;
}

Insert image description here

注:程序中用文件流类ofstream,它是在头文件fstream中定义的,用vc6.0时要把这个头文件包含进来。

5. Operation on binary files

       Binary files are written to disk files in the form of data storage in memory, so they are also called image files of memory data.
       The operation of binary files is similar to the operation of text files: first define the file stream object, then open the file, and close the file after use. When opening, you must specify that the file is stored in binary form. Binary files can be used as input files or output files, or as files that can be both input and output. This is different from ASCII files.

  1. Use the member functions read and write to read and write files respectively.
    To read binary files, use the read member function of the istream class; to write binary files, use the write member function of the ostream class.
    Their function prototypes are:
    istream& read(char * bu, int len);
    ostream& write( const char * bu, int len);
    The character pointer bu points to the starting position of the data to be read or written in the memory. len is the number of data bytes to be read and written at one time (data length).
    Calling format:
    input file stream object.read(memory pointer, length);
    output file stream object.write(memory pointer, length);

Example: Write a batch of data into a disk file in binary form, read the data from the file and display it on the screen.

struct student
{
    
    	char name[20];
 	int num;
 	int age;
 	char sex;
};
int main()
{
    
     
    student stud[3]={
    
     "Li",   1001,18,'f',    "Fun",1002,19,'m', "Wang",1004,17,'f'};
    ofstream outfile("stud.dat",ios::binary);
    if(!outfile)  {
    
      cerr<<"open error!"<<endl;      abort();  }
    outfile.write( (char *)&stud,sizeof(stud));
    outfile.close();
    return 0;
}
int main()
{
    
    
	student stud[3]; 	int i;
	ifstream infile("stud.dat", ios::binary);
	if (!infile) {
    
     cerr << "open error!" << endl;	abort(); }
	infile.read((char*)stud, sizeof(stud));
	infile.close();
	for (i = 0; i < 3; i++)
	{
    
    
		cout << "NO." << i + 1 << endl;
		cout << "姓名:" << stud[i].name << endl;
		cout << "学号:" << stud[i].num << endl;
		cout << "年龄:" << stud[i].age << endl;
		cout << "性别:" << stud[i].sex << endl << endl;
	}
	return 0;
}

Insert image description here

  1. Stream class member functions related to file pointers
    In order to randomly read data in a binary file, the disk file uses a pointer to represent the current location to be accessed. The pointer is automatically modified every time the file is read or written. Make the pointer always point to the current location to be accessed. For binary files, the program is allowed to control pointer movement to achieve random access to the file. The file stream class provides member functions related to file pointers.
    Insert image description here
    The position and displacement in the function parameter file are in bytes and are long integers. The reference position indicates what is the starting point for movement.
    The ios class is defined as:
    ios::beg starts at the beginning of the file, which is the default.
    ios::cur starts from the current position of the pointer.
    ios::end starts from the end of the file.
  2. Randomly access binary data files.
    Use the member functions of the stream class to move the file pointer to achieve random access to data in any byte in the file.

Example: There are five students’ data, and the requirements are:
1) Write them to a disk file
2) Read the 1st, 3rd, and 5th student data from the disk file and display it
3) Modify the 3rd student’s data and save it to the original location
4 ) Read the modified 5 student data from the disk file and display it

struct student
{
    
    
	int num;   char name[20];   float score;
};
int main()
{
    
    
	int i;
	student stud[5] = {
    
     1001,"Li",85,1002,"Fun",97.5,1004,"Wang",54,1006,"Tan",76.5,1010,"ling",96 };
	fstream iofile("stud.dat", ios::in | ios::out | ios::binary);
	if (!iofile)
	{
    
    
		cerr << "open error!" << endl;   abort();
	}
	for (i = 0; i < 5; i++)
		iofile.write((char *)&stud[i], sizeof(stud[i]));
	student stud1[5];
	for (i = 0; i < 5; i = i + 2)
	{
    
    
		iofile.seekg(i * sizeof(stud[i]), ios::beg);
		iofile.read((char *)&stud1[i / 2], sizeof(stud1[i]));
		cout << stud1[i / 2].num << " " << stud1[i / 2].name << " "<< stud1[i / 2].score << endl;
	}
	cout << endl;
	stud[2].num = 1012;
	strcpy(stud[2].name, "Wu");
	stud[2].score = 60;
	iofile.seekp(2 * sizeof(stud[0]), ios::beg);
	iofile.write((char *)&stud[2], sizeof(stud[2]));
	iofile.seekg(0, ios::beg);
	for (i = 0; i < 5; i++)
	{
    
    
		iofile.read((char *)&stud[i], sizeof(stud[i]));
		cout << stud[i].num << " " << stud[i].name << " "<< stud[i].score << endl;
	}
	iofile.close();
	return 0;
}

Insert image description here

5. String stream

       The string stream uses a user-defined character array (string) in memory as the input and output object, that is, writing data to the memory array or reading data from the memory character array.
       String streams also need buffers. When reading or writing, the data in the stream buffer continues to increase. When the buffer is full or a newline character is encountered, the data in the buffer is written together into a character array or assigned to a specified variable.


  1. The constructor prototype of the ostrstream class to create a string stream object is:
    ostrstream::ostrstream(char *bu, int n, int mode =ios::out);

  2. The constructor prototype of the istrstream class to create a read string stream object is:
    istrstream::istrstream( char *bu, int n);
    istrstream::istrstream( char *bu);

  3. The constructor prototype of the strstream class to create a read and write string stream object is:
    strstream::strstream(char *bu, int n, int mode);

Example: To store 10 integers in a character array c, with spaces as delimiters, it is required to put them into the integer array in ascending order, and then write them into the original character array.

#include <iostream>
#include <iomanip>
#include<fstream>
#include<strstream>
using namespace std;
int main()
{
    
    
	char c[50] = "12 34 65 -23 -32 33 61 99 321 32";
	int a[10], i, j, t;
	cout << "array c:" << c << endl;
	istrstream strin(c, sizeof(c));
	for (i = 0; i < 10; i++)
		strin >> a[i];
	cout << "array a:";
	for (i = 0; i < 10; i++)
		cout << a[i] << " ";
	cout << endl;
	for (i = 0; i < 9; i++)
		for (j = 0; j < 9 - i; j++)
			if (a[j] > a[j + 1])
			{
    
    
				t = a[j]; a[j] = a[j + 1]; a[j + 1] = t;
			}
	ostrstream strout(c, sizeof(c));
	for (i = 0; i < 10; i++)
		strout << a[i] << " ";
	strout << ends;
	cout << "array c:" << c << endl;
	return 0;
}

Insert image description here

Guess you like

Origin blog.csdn.net/weixin_43312470/article/details/108045979