- chen2312 的博客
C++超快读(重构)
- @ 2025-10-5 15:00:34
增加了filefast,fasterror和filefasterror
#include<bits/stdc++.h>
using namespace std;
#if defined(_WIN32)
#include <fcntl.h>
#include <io.h>
#else
#include <unistd.h>
#endif
#define BUF_SIZE (1 << 16)
#define STR_BUF_SIZE ((1 << 24) + 1)
#define Ciallo int // 可自定义默认整数类型
namespace fastio {
class FastEndl{
}fastendl;
// 读取模式枚举
enum ReadMode {
DEFAULT, // 默认模式(按空白分隔)
LINE, // 行模式(按换行分隔)
RAW, // 原始模式(不跳过空白)
BINARY // 二进制模式
};
// 布尔值输出格式
enum BoolFormat {
DIGIT, // 数字格式(1/0)
TEXT // 文本格式(true/false)
};
// ==================== 基础类:FastIOBase ====================
class FastIOBase {
protected:
// 字符串处理缓冲区
static char str_buf[STR_BUF_SIZE];
// 全局配置
ReadMode current_mode; // 当前读取模式
BoolFormat bool_format; // 布尔值输出格式
// 跳过空白字符(根据当前模式)
virtual void skip_whitespace() = 0;
// 判断是否到达结尾
virtual bool eof() = 0;
// 读取一个字符
virtual char getc_faster() = 0;
// 写入一个字符
virtual void putc_faster(char c) = 0;
public:
FastIOBase() : current_mode(DEFAULT), bool_format(DIGIT) {}
virtual ~FastIOBase() = default;
// 设置读取模式
void set_read_mode(ReadMode mode) {
current_mode = mode;
}
// 设置布尔值输出格式
void set_bool_format(BoolFormat format) {
bool_format = format;
}
// 刷新输出缓冲区
virtual void flush() = 0;
// ==================== 输入运算符重载(>>) ====================
// 有符号整数输入
template<typename T>
typename std::enable_if<std::is_integral<T>::value && std::is_signed<T>::value, FastIOBase&>::type
operator>>(T& x) {
x = 0;
bool neg = false;
char c = getc_faster();
// 跳过非数字字符,记录符号
while (!isdigit(c) && !eof()) {
if (c == '-') neg = true;
c = getc_faster();
}
// 读取数字部分
while (isdigit(c) && !eof()) {
x = x * 10 + (c - '0');
c = getc_faster();
}
// 应用符号
if (neg) x = -x;
return *this;
}
// 无符号整数输入
template<typename T>
typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value, FastIOBase&>::type
operator>>(T& x) {
x = 0;
char c = getc_faster();
// 跳过非数字字符
while (!isdigit(c) && !eof()) c = getc_faster();
// 读取数字部分
while (isdigit(c) && !eof()) {
x = x * 10 + (c - '0');
c = getc_faster();
}
return *this;
}
// 浮点数输入
template<typename T>
typename std::enable_if<std::is_floating_point<T>::value, FastIOBase&>::type
operator>>(T& x) {
x = 0;
bool neg = false;
char c = getc_faster();
// 跳过无关字符(寻找数字、小数点或符号)
while (!isdigit(c) && c != '.' && c != '-' && !eof()) {
c = getc_faster();
}
// 处理符号
if (c == '-') {
neg = true;
c = getc_faster();
}
T factor = 1.0; // 小数部分的因子
bool after_dot = false;
// 读取整数和小数部分
while ((isdigit(c) || c == '.') && !eof()) {
if (c == '.') {
after_dot = true;
} else {
if (after_dot) {
factor *= 0.1;
x += factor * (c - '0');
} else {
x = x * 10 + (c - '0');
}
}
c = getc_faster();
}
// 处理指数部分(如123e-4)
if (c == 'e' || c == 'E') {
int exp = 0;
bool exp_neg = false;
c = getc_faster();
// 指数符号
if (c == '-') {
exp_neg = true;
c = getc_faster();
} else if (c == '+') {
c = getc_faster();
}
// 读取指数值
while (isdigit(c) && !eof()) {
exp = exp * 10 + (c - '0');
c = getc_faster();
}
// 应用指数
if (exp_neg) {
while (exp--) x /= 10.0;
} else {
while (exp--) x *= 10.0;
}
}
// 应用符号
if (neg) x = -x;
return *this;
}
// 字符输入(跳过空白)
FastIOBase& operator>>(char& c) {
c = getc_faster();
// 跳过空白字符(除非是原始模式)
while (isspace(c) && !eof()) c = getc_faster();
return *this;
}
// 布尔值输入(支持t/T/1为true,其他为false)
FastIOBase& operator>>(bool& b) {
char c = getc_faster();
if (c == EOF) {
b = false;
return *this;
}
// 跳过非字母数字字符
while (!isalnum(c) && !eof()) {
c = getc_faster();
if (c == EOF) {
b = false;
return *this;
}
}
// 判断布尔值
b = (c == 't' || c == 'T' || c == '1');
// 跳过当前值的剩余字符
while (c != EOF && !isspace(c) && !eof()) {
c = getc_faster();
}
return *this;
}
// C风格字符串输入(按空白分隔)
FastIOBase& operator>>(char* s) {
char c = getc_faster();
// 跳过前导空白
while (isspace(c) && !eof()) c = getc_faster();
// 读取直到空白或结束
while (!isspace(c) && c != EOF && !eof()) {
*s++ = c;
c = getc_faster();
}
*s = '\0'; // 终止符
return *this;
}
// 字符串输入(根据模式读取)
FastIOBase& operator>>(std::string& s) {
s.clear();
// 二进制模式:读取整个流
if (current_mode == BINARY) {
while (true) {
if (eof()) break;
size_t bytes_read = read_binary(str_buf, STR_BUF_SIZE);
if (bytes_read == 0) break;
s.append(str_buf, bytes_read);
}
return *this;
}
// 非原始模式:跳过前导空白
if (current_mode != RAW) skip_whitespace();
// 读取直到分隔符
char c;
while (!eof() && (c = getc_faster()) != EOF) {
if (current_mode == LINE) {
// 行模式:遇到换行则停止
if (c == '\n' || c == '\r') break;
} else if (current_mode != RAW) {
// 默认模式:遇到空白则停止
if (isspace(c)) break;
}
s += c;
}
return *this;
}
// ==================== 输出运算符重载(<<) ====================
// 无符号整数输出
template<typename T>
typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value, FastIOBase&>::type
operator<<(T x) {
if (x == 0) {
putc_faster('0');
return *this;
}
// 用栈存储数字的逆序
static char stack[20];
int top = 0;
while (x) {
stack[top++] = x % 10 + '0';
x /= 10;
}
// 逆序输出
while (top--) {
putc_faster(stack[top]);
}
return *this;
}
// 有符号整数输出
template<typename T>
typename std::enable_if<std::is_integral<T>::value && std::is_signed<T>::value, FastIOBase&>::type
operator<<(T x) {
if (x < 0) {
putc_faster('-'); // 输出负号
// 转换为无符号类型处理(避免溢出)
*this << static_cast<typename std::make_unsigned<T>::type>(-x);
} else {
*this << static_cast<typename std::make_unsigned<T>::type>(x);
}
return *this;
}
// 浮点数输出(保留6位小数)
template<typename T>
typename std::enable_if<std::is_floating_point<T>::value, FastIOBase&>::type
operator<<(T x) {
if (x < 0) {
putc_faster('-');
x = -x;
}
// 输出整数部分
long long integer = static_cast<long long>(x);
*this << integer;
// 输出小数部分(保留6位)
T fractional = x - integer;
if (fractional > 1e-9) { // 存在有效小数
putc_faster('.');
fractional += 1e-7; // 四舍五入修正
for (int i = 0; i < 6; i++) {
fractional *= 10;
int digit = static_cast<int>(fractional);
putc_faster('0' + digit);
fractional -= digit;
}
}
return *this;
}
// 字符输出
FastIOBase& operator<<(char c) {
putc_faster(c);
return *this;
}
// 布尔值输出(根据格式)
FastIOBase& operator<<(bool value) {
if (bool_format == DIGIT) {
putc_faster(value ? '1' : '0');
} else {
const char* str = value ? "true" : "false";
while (*str) putc_faster(*str++);
}
return *this;
}
// 字符串输出
FastIOBase& operator<<(const std::string& s) {
for (char c : s) putc_faster(c);
return *this;
}
// C风格字符串输出
FastIOBase& operator<<(const char* s) {
while (*s) putc_faster(*s++);
return *this;
}
// ==================== 辅助功能 ====================
// 读取一行(忽略回车符)
void read_line(std::string& s) {
s.clear();
char c;
while (!eof() && (c = getc_faster()) != EOF) {
if (c == '\n') break; // 遇到换行停止
if (c != '\r') s += c; // 忽略回车符
}
}
// 换行并刷新
FastIOBase& writeln() {
putc_faster('\n');
flush();
return *this;
}
// 输出内容并换行
template<typename T>
FastIOBase& writeln(const T& x) {
*this << x;
return writeln();
}
// ==================== fastendl 支持 ====================
FastIOBase& operator<<(FastEndl) {
putc_faster('\n');
flush();
return *this;
}
// 兼容标准库的 std::endl
FastIOBase& operator<<(std::ostream& (*manip)(std::ostream&)) {
if (manip == static_cast<std::ostream& (*)(std::ostream&)>(std::endl)) {
putc_faster('\n');
flush();
}
return *this;
}
protected:
// 二进制读取(子类实现)
virtual size_t read_binary(char* buf, size_t size) = 0;
};
// 静态成员初始化
char FastIOBase::str_buf[STR_BUF_SIZE];
// ==================== 标准I/O类:FastIO ====================
class FastIO : public FastIOBase {
private:
// 输入缓冲区
static char in_buf[BUF_SIZE];
static char* in_p1; // 缓冲区读指针(当前位置)
static char* in_p2; // 缓冲区尾指针
// 输出缓冲区
static char out_buf[BUF_SIZE];
static char* out_p; // 缓冲区写指针
// 从缓冲区快速读取一个字符
char getc_faster() override {
if (in_p1 == in_p2) {
// 缓冲区为空时从stdin读入
in_p2 = (in_p1 = in_buf) + fread(in_buf, 1, BUF_SIZE, stdin);
if (in_p1 == in_p2) return EOF; // 到达文件尾
}
return *in_p1++;
}
// 快速写入一个字符到缓冲区
void putc_faster(char c) override {
*out_p++ = c;
// 缓冲区即将满时刷新
if (out_p - out_buf >= BUF_SIZE - 64) flush();
}
// 跳过空白字符(根据当前模式)
void skip_whitespace() override {
if (current_mode != RAW && current_mode != BINARY) {
char c;
while ((c = getc_faster()) != EOF) {
if (current_mode == LINE) {
// 行模式下跳过换行符
if (c != '\n' && c != '\r') {
in_p1--; // 回退指针(保留非换行符)
break;
}
} else {
// 默认模式下跳过所有空白
if (!isspace(c)) {
in_p1--; // 回退指针(保留非空白符)
break;
}
}
}
}
}
// 判断是否到达文件尾
bool eof() override {
if (in_p1 < in_p2) return false; // 缓冲区还有数据
// 尝试刷新缓冲区
in_p1 = in_buf;
in_p2 = in_buf + fread(in_buf, 1, BUF_SIZE, stdin);
return in_p1 == in_p2; // 缓冲区仍为空则到达文件尾
}
// 二进制读取
size_t read_binary(char* buf, size_t size) override {
return fread(buf, 1, size, stdin);
}
public:
// 构造函数默认
FastIO() = default;
// 析构函数:刷新输出缓冲区
~FastIO() {
flush();
}
// 刷新输出缓冲区
void flush() override {
if (out_p != out_buf) {
fwrite(out_buf, 1, out_p - out_buf, stdout);
fflush(stdout);
out_p = out_buf;
}
}
// 初始化IO(跨平台设置)
static void init() {
#if defined(_WIN32)
// Windows设置二进制模式(避免CRLF转换)
_setmode(_fileno(stdin), _O_BINARY);
_setmode(_fileno(stdout), _O_BINARY);
#endif
// 可根据需要设置缓冲区模式
}
};
// 静态成员初始化
char FastIO::in_buf[BUF_SIZE];
char* FastIO::in_p1 = FastIO::in_buf;
char* FastIO::in_p2 = FastIO::in_buf;
char FastIO::out_buf[BUF_SIZE];
char* FastIO::out_p = FastIO::out_buf;
// ==================== 标准错误输出类:FastErr ====================
class FastErr {
private:
// 错误输出缓冲区
static char err_buf[BUF_SIZE];
static char* err_p; // 缓冲区写指针
// 快速写入一个字符到错误缓冲区
void putc_faster(char c) {
*err_p++ = c;
// 缓冲区即将满时刷新
if (err_p - err_buf >= BUF_SIZE - 64) flush();
}
public:
FastErr() = default;
// 析构函数:刷新错误缓冲区
~FastErr() {
flush();
}
// 刷新错误缓冲区到stderr
void flush() {
if (err_p != err_buf) {
fwrite(err_buf, 1, err_p - err_buf, stderr);
fflush(stderr);
err_p = err_buf;
}
}
// ==================== 输出运算符重载(<<) ====================
// 无符号整数输出
template<typename T>
typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value, FastErr&>::type
operator<<(T x) {
if (x == 0) {
putc_faster('0');
return *this;
}
// 用栈存储数字的逆序
static char stack[20];
int top = 0;
while (x) {
stack[top++] = x % 10 + '0';
x /= 10;
}
// 逆序输出
while (top--) {
putc_faster(stack[top]);
}
return *this;
}
// 有符号整数输出
template<typename T>
typename std::enable_if<std::is_integral<T>::value && std::is_signed<T>::value, FastErr&>::type
operator<<(T x) {
if (x < 0) {
putc_faster('-'); // 输出负号
// 转换为无符号类型处理(避免溢出)
*this << static_cast<typename std::make_unsigned<T>::type>(-x);
} else {
*this << static_cast<typename std::make_unsigned<T>::type>(x);
}
return *this;
}
// 浮点数输出(保留6位小数)
template<typename T>
typename std::enable_if<std::is_floating_point<T>::value, FastErr&>::type
operator<<(T x) {
if (x < 0) {
putc_faster('-');
x = -x;
}
// 输出整数部分
long long integer = static_cast<long long>(x);
*this << integer;
// 输出小数部分(保留6位)
T fractional = x - integer;
if (fractional > 1e-9) { // 存在有效小数
putc_faster('.');
fractional += 1e-7; // 四舍五入修正
for (int i = 0; i < 6; i++) {
fractional *= 10;
int digit = static_cast<int>(fractional);
putc_faster('0' + digit);
fractional -= digit;
}
}
return *this;
}
// 字符输出
FastErr& operator<<(char c) {
putc_faster(c);
return *this;
}
// 布尔值输出
FastErr& operator<<(bool value) {
if (value) {
const char* str = "true";
while (*str) putc_faster(*str++);
} else {
const char* str = "false";
while (*str) putc_faster(*str++);
}
return *this;
}
// 字符串输出
FastErr& operator<<(const std::string& s) {
for (char c : s) putc_faster(c);
return *this;
}
// C风格字符串输出
FastErr& operator<<(const char* s) {
while (*s) putc_faster(*s++);
return *this;
}
// ==================== 辅助功能 ====================
// 换行并刷新
FastErr& writeln() {
putc_faster('\n');
flush();
return *this;
}
// 输出内容并换行
template<typename T>
FastErr& writeln(const T& x) {
*this << x;
return writeln();
}
// ==================== fastendl 支持 ====================
FastErr& operator<<(FastEndl) {
putc_faster('\n');
flush();
return *this;
}
// 兼容标准库的 std::endl
FastErr& operator<<(std::ostream& (*manip)(std::ostream&)) {
if (manip == static_cast<std::ostream& (*)(std::ostream&)>(std::endl)) {
putc_faster('\n');
flush();
}
return *this;
}
// 删除输入操作符,防止误用
template<typename T>
FastErr& operator>>(T&) = delete;
FastErr& operator>>(char&) = delete;
FastErr& operator>>(bool&) = delete;
FastErr& operator>>(char*) = delete;
FastErr& operator>>(std::string&) = delete;
};
// 静态成员初始化
char FastErr::err_buf[BUF_SIZE];
char* FastErr::err_p = FastErr::err_buf;
// ==================== 字符串I/O类:StrFastIO ====================
class StrFastIO : public FastIOBase {
private:
// 输入字符串
std::string* in_str = nullptr;
size_t in_pos = 0;
// 输出字符串
std::string* out_str = nullptr;
// 从字符串快速读取一个字符
char getc_faster() override {
if (in_str == nullptr || in_pos >= in_str->size()) {
return EOF; // 到达字符串尾
}
return (*in_str)[in_pos++];
}
// 快速写入一个字符到字符串
void putc_faster(char c) override {
if (out_str != nullptr) {
out_str->push_back(c);
}
}
// 跳过空白字符(根据当前模式)
void skip_whitespace() override {
if (current_mode != RAW && current_mode != BINARY) {
char c;
while ((c = getc_faster()) != EOF) {
if (current_mode == LINE) {
// 行模式下跳过换行符
if (c != '\n' && c != '\r') {
in_pos--; // 回退指针(保留非换行符)
break;
}
} else {
// 默认模式下跳过所有空白
if (!isspace(c)) {
in_pos--; // 回退指针(保留非空白符)
break;
}
}
}
}
}
// 判断是否到达字符串尾
bool eof() override {
return in_str == nullptr || in_pos >= in_str->size();
}
// 二进制读取
size_t read_binary(char* buf, size_t size) override {
if (in_str == nullptr || in_pos >= in_str->size()) {
return 0;
}
size_t bytes_to_read = min(size, in_str->size() - in_pos);
memcpy(buf, in_str->data() + in_pos, bytes_to_read);
in_pos += bytes_to_read;
return bytes_to_read;
}
public:
// 构造函数
StrFastIO() = default;
// 设置输入字符串
void set_input_string(std::string& str) {
in_str = &str;
in_pos = 0;
}
// 设置输出字符串
void set_output_string(std::string& str) {
out_str = &str;
str.clear();
}
// 刷新输出(对于字符串输出,不需要特殊操作)
void flush() override {
// 字符串输出不需要刷新
}
};
// ==================== 文件I/O类:FileFastIO ====================
class FileFastIO : public FastIOBase {
private:
// 输入缓冲区
static char in_buf[BUF_SIZE];
static char* in_p1;
static char* in_p2;
// 输出缓冲区
static char out_buf[BUF_SIZE];
static char* out_p;
// 文件指针
FILE* fin;
FILE* fout;
// 从缓冲区快速读取一个字符
char getc_faster() override {
if (in_p1 == in_p2) {
// 缓冲区为空时从文件读入
in_p2 = (in_p1 = in_buf) + fread(in_buf, 1, BUF_SIZE, fin);
if (in_p1 == in_p2) return EOF;
}
return *in_p1++;
}
// 快速写入一个字符到缓冲区
void putc_faster(char c) override {
*out_p++ = c;
// 缓冲区即将满时刷新
if (out_p - out_buf >= BUF_SIZE - 64) flush();
}
// 跳过空白字符(根据当前模式)
void skip_whitespace() override {
if (current_mode != RAW && current_mode != BINARY) {
char c;
while ((c = getc_faster()) != EOF) {
if (current_mode == LINE) {
// 行模式下跳过换行符
if (c != '\n' && c != '\r') {
in_p1--;
break;
}
} else {
// 默认模式下跳过所有空白
if (!isspace(c)) {
in_p1--;
break;
}
}
}
}
}
// 判断是否到达文件尾
bool eof() override {
if (in_p1 < in_p2) return false;
in_p1 = in_buf;
in_p2 = in_buf + fread(in_buf, 1, BUF_SIZE, fin);
return in_p1 == in_p2;
}
// 二进制读取
size_t read_binary(char* buf, size_t size) override {
return fread(buf, 1, size, fin);
}
// 打开文件的辅助函数
bool open_file(FILE*& file, const char* filename, const char* mode, FILE* default_file) {
if (file != default_file && file != nullptr) {
fclose(file);
}
file = fopen(filename, mode);
if (!file) {
file = default_file;
return false;
}
return true;
}
public:
// 构造函数 - 默认不打开文件
FileFastIO() {
fin = stdin;
fout = stdout;
in_p1 = in_p2 = in_buf;
out_p = out_buf;
}
// 构造函数 - 打开文件
FileFastIO(const char* input_file, const char* output_file) {
// 打开输入文件
if (input_file) {
fin = fopen(input_file, "rb");
if (!fin) {
fin = stdin;
}
} else {
fin = stdin;
}
// 打开输出文件
if (output_file) {
fout = fopen(output_file, "wb");
if (!fout) {
fout = stdout;
}
} else {
fout = stdout;
}
// 初始化缓冲区指针
in_p1 = in_p2 = in_buf;
out_p = out_buf;
}
// 析构函数:刷新输出缓冲区并关闭文件
~FileFastIO() {
flush();
if (fin != stdin) fclose(fin);
if (fout != stdout) fclose(fout);
}
// 刷新输出缓冲区
void flush() override {
if (out_p != out_buf) {
fwrite(out_buf, 1, out_p - out_buf, fout);
fflush(fout);
out_p = out_buf;
}
}
// ==================== 文件操作函数 ====================
// 读取文件
bool readfile(const char* filename, const char* mode = "r") {
flush();
bool success = open_file(fin, filename, mode, stdin);
in_p1 = in_p2 = in_buf; // 重置输入缓冲区
return success;
}
// 写入文件
bool writefile(const char* filename, const char* mode = "w") {
flush();
bool success = open_file(fout, filename, mode, stdout);
out_p = out_buf; // 重置输出缓冲区
return success;
}
// 重新打开输入文件
bool reopen_input(const char* filename) {
return readfile(filename, "rb");
}
// 重新打开输出文件
bool reopen_output(const char* filename) {
return writefile(filename, "wb");
}
// 关闭输入文件(回退到stdin)
void close_input() {
flush();
if (fin != stdin) {
fclose(fin);
fin = stdin;
}
in_p1 = in_p2 = in_buf;
}
// 关闭输出文件(回退到stdout)
void close_output() {
flush();
if (fout != stdout) {
fclose(fout);
fout = stdout;
}
out_p = out_buf;
}
// 获取当前输入文件名(如果是文件的话)
const char* get_input_filename() const {
return (fin == stdin) ? "stdin" : "file";
}
// 获取当前输出文件名(如果是文件的话)
const char* get_output_filename() const {
return (fout == stdout) ? "stdout" : "file";
}
// 检查是否正在使用文件输入
bool is_using_file_input() const {
return fin != stdin;
}
// 检查是否正在使用文件输出
bool is_using_file_output() const {
return fout != stdout;
}
};
// 静态成员初始化
char FileFastIO::in_buf[BUF_SIZE];
char* FileFastIO::in_p1 = FileFastIO::in_buf;
char* FileFastIO::in_p2 = FileFastIO::in_buf;
char FileFastIO::out_buf[BUF_SIZE];
char* FileFastIO::out_p = FileFastIO::out_buf;
// ==================== 文件错误输出类:FileFastErr ====================
class FileFastErr {
private:
// 错误输出缓冲区
static char err_buf[BUF_SIZE];
static char* err_p;
// 错误文件指针
FILE* ferr;
// 快速写入一个字符到错误缓冲区
void putc_faster(char c) {
*err_p++ = c;
// 缓冲区即将满时刷新
if (err_p - err_buf >= BUF_SIZE - 64) flush();
}
// 打开文件的辅助函数
bool open_file(FILE*& file, const char* filename, const char* mode, FILE* default_file) {
if (file != default_file && file != nullptr) {
fclose(file);
}
file = fopen(filename, mode);
if (!file) {
file = default_file;
return false;
}
return true;
}
public:
// 构造函数 - 默认不打开文件
FileFastErr() {
ferr = stderr;
err_p = err_buf;
}
// 构造函数 - 打开错误文件
FileFastErr(const char* error_file) {
// 打开错误文件
if (error_file) {
ferr = fopen(error_file, "wb");
if (!ferr) {
// 如果无法打开错误文件,回退到stderr
ferr = stderr;
}
} else {
ferr = stderr;
}
// 初始化缓冲区指针
err_p = err_buf;
}
// 析构函数:刷新错误缓冲区并关闭文件
~FileFastErr() {
flush();
if (ferr != stderr) fclose(ferr);
}
// 刷新错误缓冲区
void flush() {
if (err_p != err_buf) {
fwrite(err_buf, 1, err_p - err_buf, ferr);
fflush(ferr);
err_p = err_buf;
}
}
// ==================== 输出运算符重载(<<) ====================
// 无符号整数输出
template<typename T>
typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value, FileFastErr&>::type
operator<<(T x) {
if (x == 0) {
putc_faster('0');
return *this;
}
// 用栈存储数字的逆序
static char stack[20];
int top = 0;
while (x) {
stack[top++] = x % 10 + '0';
x /= 10;
}
// 逆序输出
while (top--) {
putc_faster(stack[top]);
}
return *this;
}
// 有符号整数输出
template<typename T>
typename std::enable_if<std::is_integral<T>::value && std::is_signed<T>::value, FileFastErr&>::type
operator<<(T x) {
if (x < 0) {
putc_faster('-'); // 输出负号
// 转换为无符号类型处理(避免溢出)
*this << static_cast<typename std::make_unsigned<T>::type>(-x);
} else {
*this << static_cast<typename std::make_unsigned<T>::type>(x);
}
return *this;
}
// 浮点数输出(保留6位小数)
template<typename T>
typename std::enable_if<std::is_floating_point<T>::value, FileFastErr&>::type
operator<<(T x) {
if (x < 0) {
putc_faster('-');
x = -x;
}
// 输出整数部分
long long integer = static_cast<long long>(x);
*this << integer;
// 输出小数部分(保留6位)
T fractional = x - integer;
if (fractional > 1e-9) { // 存在有效小数
putc_faster('.');
fractional += 1e-7; // 四舍五入修正
for (int i = 0; i < 6; i++) {
fractional *= 10;
int digit = static_cast<int>(fractional);
putc_faster('0' + digit);
fractional -= digit;
}
}
return *this;
}
// 字符输出
FileFastErr& operator<<(char c) {
putc_faster(c);
return *this;
}
// 布尔值输出
FileFastErr& operator<<(bool value) {
if (value) {
const char* str = "true";
while (*str) putc_faster(*str++);
} else {
const char* str = "false";
while (*str) putc_faster(*str++);
}
return *this;
}
// 字符串输出
FileFastErr& operator<<(const std::string& s) {
for (char c : s) putc_faster(c);
return *this;
}
// C风格字符串输出
FileFastErr& operator<<(const char* s) {
while (*s) putc_faster(*s++);
return *this;
}
// ==================== 辅助功能 ====================
// 换行并刷新
FileFastErr& writeln() {
putc_faster('\n');
flush();
return *this;
}
// 输出内容并换行
template<typename T>
FileFastErr& writeln(const T& x) {
*this << x;
return writeln();
}
// ==================== fastendl 支持 ====================
FileFastErr& operator<<(FastEndl) {
putc_faster('\n');
flush();
return *this;
}
// 兼容标准库的 std::endl
FileFastErr& operator<<(std::ostream& (*manip)(std::ostream&)) {
if (manip == static_cast<std::ostream& (*)(std::ostream&)>(std::endl)) {
putc_faster('\n');
flush();
}
return *this;
}
// ==================== 文件操作函数 ====================
// 打开错误文件
bool open_error_file(const char* filename, const char* mode = "w") {
flush();
bool success = open_file(ferr, filename, mode, stderr);
err_p = err_buf; // 重置错误缓冲区
return success;
}
// 重新打开错误文件
bool reopen_error(const char* filename) {
return open_error_file(filename, "wb");
}
// 关闭错误文件(回退到stderr)
void close_error() {
flush();
if (ferr != stderr) {
fclose(ferr);
ferr = stderr;
}
err_p = err_buf;
}
// 获取当前错误文件名(如果是文件的话)
const char* get_error_filename() const {
return (ferr == stderr) ? "stderr" : "file";
}
// 检查是否正在使用文件错误输出
bool is_using_file_error() const {
return ferr != stderr;
}
// 删除输入操作符,防止误用
template<typename T>
FileFastErr& operator>>(T&) = delete;
FileFastErr& operator>>(char&) = delete;
FileFastErr& operator>>(bool&) = delete;
FileFastErr& operator>>(char*) = delete;
FileFastErr& operator>>(std::string&) = delete;
};
// 静态成员初始化
char FileFastErr::err_buf[BUF_SIZE];
char* FileFastErr::err_p = FileFastErr::err_buf;
// 全局IO对象
static FastIO fast; // 标准I/O
static FastErr fasterr; // 标准错误输出
static StrFastIO strfast; // 字符串I/O
static FileFastIO filefast; // 文件I/O(全局实例)
// FileFastErr 需要自己创建实例,因为需要指定文件名
}
using namespace fastio;
// 使用示例:
int main() {
// 1. 使用标准I/O
int a, b;
fast >> a >> b;
fast << "Sum: " << a + b << fastendl;
// 2. 使用标准错误输出
fasterr << "Debug: a=" << a << ", b=" << b << fastendl;
// 3. 使用字符串I/O
string input_str = "123 456 hello";
string output_str;
strfast.set_input_string(input_str);
strfast.set_output_string(output_str);
int x, y;
string s;
strfast >> x >> y >> s;
strfast << "x=" << x << ", y=" << y << ", s=" << s;
cout << "String output: " << output_str << endl;
// 4. 使用全局文件I/O实例
filefast.readfile("input.in", "r"); // 以读取模式打开输入文件
filefast.writefile("output.out", "w"); // 以写入模式打开输出文件
// filefast.writefile("output.out", "a"); // 或者以追加模式打开输出文件
int n;
filefast >> n;
for (int i = 0; i < n; i++) {
int val;
filefast >> val;
filefast << "Value " << i << ": " << val << '\n';
}
// 5. 使用文件错误输出
FileFastErr file_err;
file_err.open_error_file("error.log", "w"); // 打开错误日志文件
file_err << "Program started" << fastendl;
if (n == 0) {
file_err << "Warning: n is zero!" << fastendl;
}
// 6. 动态切换文件
filefast.readfile("input2.in", "r");
filefast.writefile("output2.out", "w");
// 处理另一个文件
int m;
filefast >> m;
filefast << "Processing second file, m = " << m << fastendl;
// 关闭文件,回退到标准I/O
filefast.close_input();
filefast.close_output();
// 现在filefast将使用stdin和stdout
filefast << "Now using standard I/O" << fastendl;
return 0;
}