输入输出
标准输入输出
c语言使用printf和wprintf作为标准输出函数;
int wprintf(const wchar_t *format, ...);
用wprintf()时,要用%ls表示wchar_t的字符串,用%s表示char的字符串; Windows 的实现用%ls、%s都可以正确输出wchar_t字符串。
C++使用cout和wcout作为标准输出函数;
在输出Unicode编码的宽字符时,使用带前缀“w”的函数;在使用之前需要设置程序的区域,即调用setlocale函数(C语言),或使用locale类和流对象的imbue(C++)。
char * setlocale ( int category, const char * locale );
在Linux下,可以使用 locale -a 命令查看系统中所有已配置的 locale。用不带选项的 locale命令查看当前 Shell 中活动的 locale。用locale -m 命令查看locale系统支持的所有可用的字符集编码。
Linux下wcout可以输出char型字符串和wchar_t型字符串。运行环境的locale设置要和程序中setlocale()设定的locale一致,比如:终端的活动字符集、环境变量(一般用LANG),要设置为*.UTF-8,才能显示setlocale(LC_ALL, "zh_CN.UTF-8") 设定的wchar_t的中文字符。
不要混用char和 wchar_t 版本的流操作函数,否则会导致这些函数运行异常。
fscanf 在Linux下,只能正常读取UTF-8(ASCII)编码的文本,不能对其他编码格式进行自动解码。 如果是其他编码,则需要以字节方式读入,手动转换为UTF-8编码,才能正常使用。
| I/O Streams | IO desc | Details | Operators |
|---|---|---|---|
std::cin | stdin | reads from buffer. | cin >> var |
std::cout | stdout | output to console when buffer full. | cout << var |
std::clog | stderr | output to console when buffer full. | clog << var |
std::cerr | stderr | immediately writes to console. | cerr << var |
using namespace std;
getline(cin, s); // read entire line
getline(cin, s, ch); // read until next character ch
数据流
C++输入输出通过输入输出流类来完成,在头文件“iostream”中定义了这些类的基类:
• istream:从流中读取数数据。
• ostream:写入数据到流中。
• iostream:对流进行读和写操作,继承自istream和ostream。
所有输入输出流类,还有其宽字符版本,以支持国际化。宽字符版本在普通版本前增加“w”前缀。所有类型均由basic_xxxstream通过模板参数(charT, traits)实例化(类似于string类型)。
std::cin是istream类型对象;std::cout是ostream类型对象
格式化
所有设置函数未接收参数时,返回当前的设置。
标识
old_flags = cout.flags(ios::right|ios::hex); // set all flags
old_flags = cout.setf(flags, mask); //only set specified flags
void unsetf(fmtflags mask); // clear specified flags
flags()设置流的所有标识(未给出的清空),而setf仅设置给出的标识(未给出的不变)。
标识为两种:1) 独立标识;2) 选择性标识:一组包括多个标识,但同时只能设置一个。mask用于设置选择性标识,用以清空非当前设置的同组其他标识。
标识定义在
ios类中,类型为fmtflags(bitmask)。
独立标识
| 独立标识 | 说明 |
|---|---|
boolalpha | 以字符串格式读写bool值 (true and false) |
showbase | 输出前缀(0x,o) |
showpoint | 浮点数总是输出小数点 |
showpos | 整数输出+号 |
skipws | 跳过输入内容前面的空白 |
unitbuf | flush output after each inserting operation. |
uppercase | 替换未大写字母 in certain insertion operations. |
选择性标识
| 选择性标识位 | 掩码 | 说明 |
|---|---|---|
left, right or internal | adjustfield | 对齐方式 |
dec, oct or hex | basefield | 计数进制 |
scientific or fixed | floatfield | 浮点数表示法 |
使用操作符格式化:
cout << fixed;
cout << scientific;
cout << boolalpha; // booleans as string
宽度
ios.width(int n); // cout << std::setw() #include <iomanip>
ios.fill(char ch); // 填充字符
显示数据的最小宽度,数据内容少于该宽度将填充字符,填充字符位置更具对齐方式决定(adjustfield)。
精度
精度的具体定义取决于使用定点法或科学计数法。
ios.precision(int n) // cout << std::setprecision(n)
locale
locale loc = ios.getloc()
状态
iostate s = ios.rdstate(); // 返回内部错误状态标识
bool tf = ios.good();// goodbit: True if no errors
bool tf = ios.eof(); // eofbit:
bool tf = ios.fail();// failbit|badbit: IO逻辑错误(在输入模式下执行输出,识别内容失败)
bool tf = ios.bad(); // badbit: IO操作读写错误
badbit:标志着系统级的故障,如无法恢复的读写错误。如果出现了这类错误,则该流通常就不能再继续使用了。
failbit:出现的是可恢复的错误,如在希望获得数值型数据时输入了字符,此时则设置 failbit 标志,这种导致设置 failbit的问题通常是可以修正的。
eofbit:遇到文件结束符时设置。
当流出现错误时,缓存中的错误内容不会自动被丢弃,再该流上继续执行操作还会产生错误。
cin.clear(state=goodbit) // 重置状态
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 清除缓存
设置异常触发:根据设置的状态触发异常。
ios.exceptions(iostate except);
读写操作符
“<<”操作符(print()):将数据格式化输出到输出流。
“>>”操作符:从输入流扫描并格式化读入数据。
重载运算符
std::ostream& operator << (std::ostream& os, point const& p) {
return os << '(' << p.x << ',' << p.y << ')';
}
std::istream& operator >> (std::istream& is, point& p) {
return is >> p.x >> p.y;
}
https://hackingcpp.com/cpp/std/istream_recover_from_errors.html
读写方法
std::getline(istream&, string&, stopat='\n')
std::istream.ignore(n, c) // skip n chars, or until char 'c'.
流式字符串读写
ostringstream,istringstream。
流式文件读写
用于普通文件读写的输入输出流类在头文件“fstream”中声明,包含以下类型:
#include <fstream>
using namespace std;
ifstream; // 继承`istream`,用于读文件。
ofstream; // 继承`ostream`,用于写文件。
fstream; // 继承`iostream`,用于读写文件。
fstream中声明的类除了继承下来的行为外,还定义了两个新操作——open和close,以及形参为要打开的文件名的构造函数。
std::ofstream os {"squares.txt", ios::in}; // ios::binary
os.open("squares.txt");
os.good();
os.close(); // file can be automatically closed