类输入输出
I/O 类
?
这些类型的C++ 不直接处理输入输出, 而是通过一组定义在标准库中的类型来处理 I/O .支持从设备读取数据和向设备写入数据的输入/输出操作。设备可以是文件、控制台窗口等。其他类型允许内存输入/输出,即从字符串读取数据和向字符串写入数据。
?
I/O类主要包括iostream,sstream和fstream. iostream定义了读写流,的基本类型fsstream定义了读写命名文件的类型而sstream定义了读写内存 string 对象.的类型
?
I/O 对象无法拷贝和赋值.此外,由于输入/输出操作的功能读取和写入输入/输出对象将改变其状态,I/O 操作函数传递的参数和返回的引用不能为 const.
?
I/O操作的内在问题是可能发生错误,所以在I/O库中定义了一些函数和标志,即条件状态.你可以自己搜索这些条件状态。
?
iostream
?
Iostream包含istream和ostream,即从stream读取数据和向stream写入数据,而iostream继承了这两个库,即读写stream和由于 iostream 继承于 istream 和 ostream , 因此在没有熟悉 I/O 中的函数及操纵符之前尽量使用 istream 和 ostream 声明和定义对象.
?
每个iostream对象都可以使用操纵符来修改流的格式状态。在之前的研究中,c语言中常见的endl是一个运算符,它的功能是输出一个换行并刷新缓冲区.这里有一些常用的格式化I/O运算符。
?
格式化 I/O 操纵符
?
boolalpha / noboolalpha
?
将 true 和 false 输出为字符串 / 将 true 和 false 输出为 1, 0
?
#包含iostream
使用命名空间标准;
int main(空)
{
cout boolalpha true ' ' false endl//输出真假。
cout no pool alpha true ' ' false endl;//输出1 0。
返回0;
}
?
dec / hex / oct
?
输出十进制 / 十六进制 / 八进制
?
#包含iostream
使用命名空间标准;
int main(空)
{
int x=10
cout dec x endl//输出10。
cout十六进制x endl//输出a。
cout oct x endl//输出12。
返回0;
}
?
showbase / noshowbase
?
对整型值输出表示进制的前缀 / 对不生成表示进制的前缀
?
#包含iostream
使用命名空间标准;
int main(空)
{
int x=10
cout showbase dec x endl//输出10(不带前缀的十进制)
cout showbase十六进制x endl//输出0xa。
cout showbase oct x endl//输出012。
cout noshowbase dec x endl//输出10。
cout no showbase hex endl;//输出a。
cout noshowbase oct x endl//输出12。
返回0;
}
?
showpos / nosho
wpos
?
对非负数显示 + / 对非负数不显示 +
?
#include iostream
using namespace std;
int main(void)
{
int x = 10;
cout showpos x endl; //输出 +10
cout noshowpos x endl; //输出 10
return 0;
}
?
uppercase / noupppercase
?
在十六进制值中打印 0X, 在科学记数法中打印 E / 在十六进制值中打印 0x, 在科学记数法中打印 e
?
#include iostream
using namespace std;
int main(void)
{
int x = 123;
cout hex uppercase showbase x endl; //输出 0X7B
cout hex nouppercase showbase x endl; //输出 0x7b
return 0;
}
?
scientific
?
浮点值显示为科学科学记数法
?
#include iostream
using namespace std;
int main(void)
{
double x = 123;
cout scientific x endl; // 输出 1.230000e+02
return 0;
}
?
fixed
?
浮点值显示为定点十进制
?
#include iostream
using namespace std;
int main(void)
{
double x = 123;
cout fixed x endl; //输出 123.000
return 0;
}
?
showpoint / noshowpoint
?
对浮点值总是显示小数点 / 只有当浮点值包含小数部分时才显示小数点
?
#include iostream
using namespace std;
int main(void)
{
double x = 1.000;
cout showpoint x endl; //输出 1.000000
cout noshowpoint x endl; //输出 1
return 0;
}
?
skipws / noskipws
?
输入运算符跳过空白符 / 输入运算符不跳过空白符
?
#include iostream
using namespace std;
int main(void)
{
char x;
cin noskipws;
while(cin x) //输入1 2 3
cout x; //输出1 2 3
cout endl;
return 0;
}
?
hexfloat
?
浮点值显示为十六进制
?
#include iostream
using namespace std;
int main(void)
{
double x = 0.125;
cout hexfloat x endl; //输出0x8p-6
return 0;
}
?
defaultfloat
?
重置浮点数格式为十进制
?
#include iostream
using namespace std;
int main(void)
{
double x = 0.125;
cout hexfloat x endl; //输出0x8p-6
cout defaultfloat x endl; //输出0.125
return 0;
}
?
setw
?
setw(w) 读或写值的宽度为 w 个字符
?
?
left / right / internal
?
在值的右侧添加填充字符 / 在值的左侧添加填充字符 / 在符号和值之间添加填充字符
三种操纵符需要 iomanip 库中的 setw 来实现
?
#include iostream
#include iomanip
using namespace std;
int main(void)
{
int x = 12345;
cout left setw(12) x endl; //输出12345
cout right setw(12) x endl; //输出 12345
cout showpos internal setw(12) x endl; //输出+ 12345
return 0;
}
?
部分在 iomanip 中的操纵符
?
setfill
?
setfill(ch), 用 ch 填补空白
?
#include iostream
#include iomanip
using namespace std;
int main(void)
{
int x = 12345;
cout setfill('*') setw(12) x endl; //输出*******12345
return 0;
}
?
setprecision
?
setprecision(n), 将浮点精度设置为 n
?
#include iostream
#include iomanip
#include cmath
using namespace std;
int main(void)
{
cout setprecision(12) sqrt(2) endl; //输出1.41421356237
return 0;
}
?
关于 os.precision
?
os.precision(n) 作用与 setprecision 相同, 不过其返回值为设置前的浮点数精度 (默认为6), 因此往往它作为单独的语句.
?
setbase
?
setbase(n), 将整数输出为 b 进制
?
#include iostream
#include iomanip
#include cmath
using namespace std;
int main(void)
{
int x = 12345;
cout setbase(10) showbase x endl; //输出12345
cout setbase(16) showbase x endl; //输出0x3039
cout setbase(8) showbase x endl; //输出030071
return 0;
}
?
未格式化的 I/O 操作 (单字节)
?
未格式化 I/O 操作允许我们将一个流当作一个无解释的字节序列来处理
?
is.get(ch) / os.put(ch)
?
从 istream is 读取下一个字节存入字符 ch 中. 返回 is / 将字符 ch 输出到 ostream os. 返回 os
?
#include iostream
using namespace std;
int main(void)
{
char ch;
cin.get(ch); //输入 a
cout.put(ch); //输出 a
return 0;
}
?
is.get()
?
将 is 的下一个字节作为 int 返回
?
#include iostream
using namespace std;
int main(void)
{
int x;
x = cin.get(); //输入 A
cout x endl; //输出 65
return 0;
}
?
is.putback(ch)
?
将字符 ch 放回 is. 返回 is
?
#include iostream
using namespace std;
int main(void)
{
char a, b;
cin.putback('c');
cin a;
cin.putback('d');
cin b;
cout a ' ' b endl; // 输出 a b
return 0;
}
?
is.unget()
?
将 is 向后移动一个字节. 返回 is
?
#include iostream
using namespace std;
int main(void)
{
char a, b, c;
cin a b c; //输入abcdef
cout a b c endl; //输出abc
cin.unget(); //将 c 放回输入流中
char firstchar, secondchar;
cin firstchar secondchar;
cout firstchar secondchar endl; //输出cd
return 0;
}
?
is.peek()
?
将下一个字节作为 int 返回, 但不从流中删除它
?
#include iostream
using namespace std;
int main(void)
{
char a, b, c;
cin a b c; //输入abcdef
cout a b c endl; //输出abc
int x = cin.peek();
cout.put(x); //输出d
return 0;
}
?
关于 putback() 和 unget()
?
putback() 可以将指定要后退的字符放入流中, unget() 则是将最后读取的字符放入流中
?
未格式化的 I/O 操作 (多字节)
?
is.get
?
is.get(sink, size, delim) 从 is 中读取最多 size 个字节, 并保存在字符数组中, 字符数组的起始地址由 sink 给出. 读取过程中直到遇到字符 delim 或读取了 size 个字节或遇到文件尾时停止. 如果遇到了 delim , 则将其留在输入流中, 不读取出来存入 sink 中
?
#include iostream
using namespace std;
char str[14];
int main(void)
{
cin.get(str, 14, ' '); //输入Hello World
cout str endl; //输出Hello
cin str;
cout str endl; //输出 World
return 0;
}
?
?
is.getline
?
is.getline(sink, size, delim) 与 get 版本类似, 但会读取并丢弃 delim
?
#include iostream
using namespace std;
char str[14];
int main(void)
{
cin.getline(str, 14, 'W'); //输入Hello World!
cout str endl; //输出Hello
cin str;
cout str endl; //输出 orld!
return 0;
}
?
is.read
?
is.read(sink, size) 读取最多 size 个字节, 存入字符数组 sink 中. 返回 is.
?
#include iostream
using namespace std;
char str[14];
int main(void)
{
cin.read(str, 14); //输入Hello World!!
cout str endl; //输出Hello World!!
return 0;
}
?
is.gcount
?
返回上一个未格式化读取操作从 is 读取的字节数
?
#include iostream
using namespace std;
char str[14];
int main(void)
{
cin.get(str, 14, ' '); //输入Hello World!
cout cin.gcount(); //输出 5
return 0;
}
?
os.write
?
将字符数组 source 中的 size 个字节写入 os. 返回 os
?
#include iostream
using namespace std;
int main(void)
{
const char* str = "Hello, World!";
cout.write(str, 14); //输出Hello, World!
return 0;
}
?
sstream
?
sstream 定义了三个类型来支持内存 I/O, 这些类型可以向 string 写入数据, 从 string 读取流, 就像 string 是一个 I/O 流一样. 此外 sstream 也继承了 iostream 的部分特性, 例如各种操纵符等.
?
istringstream 从 string 读取数据, ostringstream 向 string 写入数据, 而头文件 stringstream 既可从 string 读取数据也可向 string 写入数据. 下面记录一些 sstream 中的基本操作. 同 iostream , 尽量先使用 istringstream 和 stringstream声明和定义对象
?
sstream strm(s)
?
strm 是一个 sstream 对象, 保存 string s 的一个拷贝. 此构造函数是 explicit 的 (即无法进行隐式类型转换)
?
#include iostream
#include string
#include sstream
using namespace std;
int main(void)
{
string str = "Hello, World!";
stringstream STR(str); //此时 STR 中保存了一个 str 的副本
return 0;
}
?
strm.str()
?
返回 strm 所保存的 string 的拷贝
?
#include iostream
#include string
#include sstream
using namespace std;
int main(void)
{
string str = "Hello, World!";
stringstream STR(str);
cout STR.str() endl; //输出 Hello, World!
return 0;
}
?
strm.str(s)
?
将 string s 拷贝到 strm 中
?
#include iostream
#include string
#include sstream
using namespace std;
int main(void)
{
string str1 = "Hello, World!";
string str2 = "Hello";
stringstream STR(str1);
cout STR.str() endl; //输出Hello, World!
STR.str(str2);
cout STR.str() endl; //输出Hello
return 0;
}
?
关于 stringstream 的重载运算符 和
?
由于 stringstream 是继承 iostream (istream, ostream ) 和 istream, ostream 的类, 因此其中也包含了它们中的重载运算符 和 , 在 stringstream 中使用它们能够非常方便的进行字符串与数字之间的转换
?
#include iostream
#include string
#include sstream
using namespace std;
int main(void)
{
stringstream sstr;
sstr 12345;
cout sstr.str() endl; //输出12345
sstr.str(""); //每次stingstream对象操作完后尽量将其清空
sstr.clear(); //清除stringstream的 I/O 状态
sstr showbase hex 0xfffff;
cout sstr.str() endl; //输出0xfffff
sstr.str("");
sstr.clear();
int x = 0;
int y = 0;
sstr dec "12345";
sstr x;
cout x endl; //输出12345
sstr.str("");
sstr.clear();
sstr hex "0xfffff";
sstr y;
cout showbase hex y endl; //输出0xfffff
sstr.str("");
sstr.clear();
return 0;
}
?
fstream
?
fstream 类继承自 ifstream 和 ofstream, 即读取文件流中的信息, 写入文件流中的信息, 而 fstream 则既可以读取文件流中的信息又可以写入文件流中的信息. 下面记录了一些 fstream 中的基本操作. 同 iostream , 先使用 ifstream 和 ofstream 声明和定义对象
?
fstream fstrm(s)
?
创建一个 fstream, 并打开名为 s 的文件. s 可以是 string, 也可以是 C 风格的字符串, 这些构造函数都是 explicit 的
?
#include iostream
#include string
#include fstream
using namespace std;
int main(int argc, char* argv[])
{
string path = "C:\\notepad.exe"; //我将C:\Windows\System32\notepad.exe复制到了C:\
fstream fstrm(path);
return 0;
}
?
fstream fstrm(s, mode)
?
在前一个构造函数上添加了打开文件的方式
?
打开文件的方式
文件模式 | 解释 |
---|---|
in | 以读的方式打开 |
out | 以写的方式打开 |
app | 每次写操作均定义到文件末尾 |
ate | 打开文件后立即定位到文件末尾 |
trunc | 截断文件 |
binary | 以二进制方式进行 I/O |
?
#include iostream
#include string
#include fstream
using namespace std;
int main(int argc, char *argv[])
{
string path = "C:\\text.txt";
fstream fstrm(path, ios::out); //在C盘创建一个text.txt
return 0;
}
?
fstream.open(s)
?
打开名为 s 的文件, 并将文件与 fstream 绑定. 其他可参考 fstream 的构造函数
?
#include iostream
#include string
#include fstream
using namespace std;
int main(int argc, char *argv[])
{
string path = "C:\\text.txt";
fstream fstrm;
fstrm.open(path, ios::out); //将在C盘创建一个text.txt
return 0;
}
?
fstrm.close()
?
关闭与 fstream 绑定的文件, 返回 void
?
#include iostream
#include string
#include fstream
using namespace std;
int main(int argc, char *argv[])
{
string path = "C:\\text.txt";
fstream fstrm;
fstrm.open(path, ios::out);
fstrm.close(); //与path绑定的fstrm已关闭
return 0;
}
?
fstrm.is_open()
?
判断文件是否已经打开且尚未关闭, 返回一个 bool 值
?
#include iostream
#include string
#include fstream
using namespace std;
int main(int argc, char *argv[])
{
string path = "C:\\text.txt";
fstream fstrm;
fstrm.open(path, ios::out);
cout fstrm.is_open() endl; //输出 1
fstrm.close();
cout fstrm.is_open() endl; //输出 0
return 0;
}
?
流随机访问
?
标准库提供了一对函数, 来定位 (seek) 到流中给定的位置, 以及告诉 (tell) 我们当前位置. 在大多数系统中, cin、cout、cerr 和 clog 的流不支持随机访问.
?
seek 和 tell 函数
?
seek 函数给定位置, tell 函数标记当前位置, seek 和 tell 函数都有 g(get) 和 p(put) 版本, 分别指 "获取 (读取) 数据" 和 "放置 (写入) 数据"
?
seekg(off, from) / seekp(off, from)
?
在一个输入流或输出流中将标记定位到 from 之前或之后 off 个字符, from 可以是下列值之一
?
beg : 偏移量相对于流开始的位置
cur : 偏移量相对于流当前的位置
end : 偏移量相对于流结束的位置
?
#include iostream
#include string
#include fstream
using namespace std;
int main(int argc, char *argv[])
{
string path = "C:\\notepad.exe";
fstream fstrm(path);
fstrm.seekg(0, ios::end);
return 0;
}
?
tellg() / tellp()
?
返回一个输入流中 (tellg) 或输出流中 (tellp) 标记的当前位置
?
#include iostream
#include string
#include fstream
using namespace std;
int main(int argc, char *argv[])
{
string path = "C:\\notepad.exe";
fstream fstrm(path);
fstrm.seekg(0, ios::end);
cout fstrm.tellg() endl; //输出132096
return 0;
}
?
seekg(pos) / seekp(pos)
?
在一个输入流或输出流中将标记重定位到给定的绝对地址. pos 通常是前一个 tellg 或 tellp 的返回值, 在此不再赘述
?
关于文件的读写
?
fstream 同样继承了 iostream , 因此 fstream 创建的对象可以使用部分 iostream 的操作
?
#include iostream
#include string
#include fstream
using namespace std;
char* text = nullptr;
int text_size = 0;
int main(int argc, char* argv[])
{
string path = "C:\\notepad.exe";
string new_path = "C:\\a.exe";
ifstream file_in(path, ios::binary | ios::in); //二进制读取notepad.exe
if (file_in.is_open())
{
file_in.seekg(0, ios::end);
text_size = file_in.tellg(); //得出文件的字节数
text = new char[text_size] {0};
file_in.seekg(0, ios::beg); //将偏移量移动至文件起始处开始读取
file_in.read(text, text_size);
}
else
cout "Failed !" endl;
ofstream file_out(new_path, ios::binary | ios::out); //二进制写入a.exe, 没有a.exe则会创建一个
if (file_out.is_open())
{
file_out.seekp(0, ios::beg); //将偏移量移动至文件起始处开始写入
file_out.write(text, text_size);
}
return 0; //C盘会出现一个名为a.exe, 内容和notepad.exe一模一样的可执行文件
}
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/70041.html