使用iostream自带的streambuf实现,可以以__cin>>和__cout<<的方式使用。
使用方法如下:
名称 | 内容 |
__cin | 输入流对象,类似<iostream>里的cin。 |
__cout | 输出流对象,类似<iostream>里的cout。 |
__cin>> | 类似<iostream>里的cin>>,从缓冲区读各种变量,跳过空白字符。 |
__cin.get(char&_Ch) | 类似<iostream>里的cin.get(ch),将缓冲区的首个字符存进_Ch变量中。 |
__cin.get() | 类似<iostream>里的cin.get(),返回缓冲区的首个字符。 |
__cin.getline(std::string &_Str,char _End='\n') | 类似<string>里的getline(cin,str,delim),从缓冲区的首个字符开始,读到_End字符为止,存进_Str变量(最后一个参数不填默认换行符)。 |
__cout<< | 类似<iostream>里的cout<<,可以向缓冲区输出各种变量。 |
__cout.flush() | 类似<iostream>里的cout.flush(),刷新缓冲区,让里面的字符输出。 |
__endl | 类似<iostream>里的endl,刷新缓冲区并换行。 |
注意:
- 控制台调试时输入完成后需要回车+(Ctrl+Z)+回车表示结束,文件输入输出无影响。
- 需要使用__endl(换行并刷新缓冲区)或__cin.flush()(手动刷新缓冲区)来输出缓冲区的字符,否则可能导致无输出。
#ifndef _GLIBCXX_IOSTREAMBUF
#define _GLIBCXX_IOSTREAMBUF 1
#pragma GCC system_header
#include<iostream>
#include<cctype>
#include<string>
namespace std _GLIBCXX_VISIBILITY(default){
_GLIBCXX_BEGIN_NAMESPACE_VERSION
//实现IO优化
const int MAXIO=1<<20;
static std::streambuf *isb=std::cin.rdbuf();
static std::streambuf *osb=std::cout.rdbuf();
char isbuf[MAXIO],*sb_p1,*sb_p2,osbuf[MAXIO],*sb_p3=osbuf;
inline int streambuf_sgetn(){
return(sb_p1==sb_p2&&(sb_p2=(sb_p1=isbuf)+isb->sgetn(isbuf,MAXIO),sb_p1==sb_p2)?EOF:*sb_p1++);
}
inline int streambuf_sputn(int _Ch){
(sb_p3-osbuf<MAXIO)?(*sb_p3++=_Ch):(osb->sputn(osbuf,sb_p3-osbuf),sb_p3=osbuf,*sb_p3++=_Ch);
return _Ch;
}
//换行并刷新缓冲区
struct __ENDL{
}__endl;
//刷新缓冲区
struct __FLUSH{
}__flush;
//输入类
class istreambuf{
private:
inline bool qread(int &_Num){
_Num=0;
int f=1;
int c=streambuf_sgetn();
while(!isdigit(c)){
if(c!=' '&&c!='\n'&&c!='\r') return false;
if(c=='-') f=-1;
c=streambuf_sgetn();
}
while(isdigit(c)){
if(c==EOF) return false;
_Num=(_Num<<3)+(_Num<<1)+(c^48);
c=streambuf_sgetn();
}
_Num*=f;
return true;
}
inline bool qread(short &_Num){
_Num=0;
int f=1;
int c=streambuf_sgetn();
while(!isdigit(c)){
if(c!=' '&&c!='\n'&&c!='\r') return false;
if(c=='-') f=-1;
c=streambuf_sgetn();
}
while(isdigit(c)){
if(c==EOF) return false;
_Num=(_Num<<3)+(_Num<<1)+(c^48);
c=streambuf_sgetn();
}
_Num*=f;
return true;
}
inline bool qread(long &_Num){
_Num=0;
int f=1;
int c=streambuf_sgetn();
while(!isdigit(c)){
if(c!=' '&&c!='\n'&&c!='\r') return false;
if(c=='-') f=-1;
c=streambuf_sgetn();
}
while(isdigit(c)){
if(c==EOF) return false;
_Num=(_Num<<3)+(_Num<<1)+(c^48);
c=streambuf_sgetn();
}
_Num*=f;
return true;
}
inline bool qread(long long &_Num){
_Num=0;
int f=1;
int c=streambuf_sgetn();
while(!isdigit(c)){
if(c!=' '&&c!='\n'&&c!='\r') return false;
if(c=='-') f=-1;
c=streambuf_sgetn();
}
while(isdigit(c)){
if(c==EOF) return false;
_Num=(_Num<<3)+(_Num<<1)+(c^48);
c=streambuf_sgetn();
}
_Num*=f;
return true;
}
inline bool qread(__int128 &_Num){
_Num=0;
int f=1;
int c=streambuf_sgetn();
while(!isdigit(c)){
if(c!=' '&&c!='\n'&&c!='\r') return false;
if(c=='-') f=-1;
c=streambuf_sgetn();
}
while(isdigit(c)){
if(c==EOF) return false;
_Num=(_Num<<3)+(_Num<<1)+(c^48);
c=streambuf_sgetn();
}
_Num*=f;
return true;
}
inline bool qread(unsigned int &_Num){
_Num=0;
int c=streambuf_sgetn();
while(!isdigit(c)){
if(c!=' '&&c!='\n'&&c!='\r') return false;
c=streambuf_sgetn();
}
while(isdigit(c)){
if(c==EOF) return false;
_Num=(_Num<<3)+(_Num<<1)+(c^48);
c=streambuf_sgetn();
}
return true;
}
inline bool qread(unsigned short &_Num){
_Num=0;
int c=streambuf_sgetn();
while(!isdigit(c)){
if(c!=' '&&c!='\n'&&c!='\r') return false;
c=streambuf_sgetn();
}
while(isdigit(c)){
if(c==EOF) return false;
_Num=(_Num<<3)+(_Num<<1)+(c^48);
c=streambuf_sgetn();
}
return true;
}
inline bool qread(unsigned long &_Num){
_Num=0;
int c=streambuf_sgetn();
while(!isdigit(c)){
if(c!=' '&&c!='\n'&&c!='\r') return false;
c=streambuf_sgetn();
}
while(isdigit(c)){
if(c==EOF) return false;
_Num=(_Num<<3)+(_Num<<1)+(c^48);
c=streambuf_sgetn();
}
return true;
}
inline bool qread(unsigned long long &_Num){
_Num=0;
int c=streambuf_sgetn();
while(!isdigit(c)){
if(c!=' '&&c!='\n'&&c!='\r') return false;
c=streambuf_sgetn();
}
while(isdigit(c)){
if(c==EOF) return false;
_Num=(_Num<<3)+(_Num<<1)+(c^48);
c=streambuf_sgetn();
}
return true;
}
inline bool qread(unsigned __int128 &_Num){
_Num=0;
int c=streambuf_sgetn();
while(!isdigit(c)){
if(c!=' '&&c!='\n'&&c!='\r') return false;
c=streambuf_sgetn();
}
while(isdigit(c)){
if(c==EOF) return false;
_Num=(_Num<<3)+(_Num<<1)+(c^48);
c=streambuf_sgetn();
}
return true;
}
inline bool qread(char &_Ch){
do{
_Ch=streambuf_sgetn();
if(_Ch==EOF) return false;
}while(_Ch==' '||_Ch=='\n'||_Ch=='\r');
return true;
}
inline bool qread(char *_Str){
int i=0;int c=streambuf_sgetn();
while(c==' '||c=='\n'||c=='\r') c=streambuf_sgetn();
while(c!=' '&&c!='\n'&&c!='\r'){
if(c==EOF){
_Str[i]='\0';
return false;
}
_Str[i]=c,++i,c=streambuf_sgetn();
}
_Str[i]='\0';
return true;
}
inline bool qread(std::string&_Str){
_Str="";
int c=streambuf_sgetn();
while(c==' '||c=='\n'||c=='\r') c=streambuf_sgetn();
while(c!=' '&&c!='\n'&&c!='\r'){
if(c==EOF) return false;
_Str.push_back(c);
c=streambuf_sgetn();
};
return true;
}
bool OK=1;
public:
operator bool(){//实现while(__cin)
bool ret=OK;
OK=1;
return ret;
}
template<typename _Tp>//重载右移运算符
inline istreambuf&operator>>(_Tp&_Value){
OK=qread(_Value);
return *this;
}
inline istreambuf&get(char&_Ch){
_Ch=streambuf_sgetn();
return *this;
}
inline char get(){
return streambuf_sgetn();
}
inline istreambuf&getline(std::string&_Str,char _End='\n'){
_Str="";
char c=streambuf_sgetn();
while(c!=_End){
_Str.push_back(c);
c=streambuf_sgetn();
}
return *this;
}
}__cin;//声明用于输入的__cin
//输出类
class ostreambuf{
private:
inline void qwrite(int _Num){
if(_Num<0) _Num=-_Num,streambuf_sputn('-');
if(_Num>9) qwrite(_Num/10);
streambuf_sputn(_Num%10+48);
}
inline void qwrite(short _Num){
if(_Num<0) _Num=-_Num,streambuf_sputn('-');
if(_Num>9) qwrite(_Num/10);
streambuf_sputn(_Num%10+48);
}
inline void qwrite(long _Num){
if(_Num<0) _Num=-_Num,streambuf_sputn('-');
if(_Num>9) qwrite(_Num/10);
streambuf_sputn(_Num%10+48);
}
inline void qwrite(long long _Num){
if(_Num<0) _Num=-_Num,streambuf_sputn('-');
if(_Num>9) qwrite(_Num/10);
streambuf_sputn(_Num%10+48);
}
inline void qwrite(__int128 _Num){
if(_Num<0) _Num=-_Num,streambuf_sputn('-');
if(_Num>9) qwrite(_Num/10);
streambuf_sputn(_Num%10+48);
}
inline void qwrite(unsigned int _Num){
if(_Num>9) qwrite(_Num/10);
streambuf_sputn(_Num%10+48);
}
inline void qwrite(unsigned short _Num){
if(_Num>9) qwrite(_Num/10);
streambuf_sputn(_Num%10+48);
}
inline void qwrite(unsigned long _Num){
if(_Num>9) qwrite(_Num/10);
streambuf_sputn(_Num%10+48);
}
inline void qwrite(unsigned long long _Num){
if(_Num>9) qwrite(_Num/10);
streambuf_sputn(_Num%10+48);
}
inline void qwrite(unsigned __int128 _Num){
if(_Num>9) qwrite(_Num/10);
streambuf_sputn(_Num%10+48);
}
inline void qwrite(char _Ch){
streambuf_sputn(_Ch);
}
inline void qwrite(char *_Str){
int i=0;
while(_Str[i]&&_Str[i]<128){
streambuf_sputn(_Str[i]),++i;
}
}
inline void qwrite(std::string _Str){
int i=0;
while(_Str[i]&&_Str[i]<128){
streambuf_sputn(_Str[i]),++i;
}
}
inline void qwrite(__ENDL _Endl){
streambuf_sputn('\n');
osb->sputn(osbuf,sb_p3-osbuf),sb_p3=osbuf;
}
inline void qwrite(__FLUSH _Flush){
osb->sputn(osbuf,sb_p3-osbuf),sb_p3=osbuf;
}
public:
template<typename _Tp>//重载左移运算符
inline ostreambuf&operator<<(_Tp _Value){
qwrite(_Value);
return *this;
}
inline ostreambuf&put(char _Ch){
streambuf_sputn(_Ch);
return *this;
}
inline void flush(){//手动刷新缓冲区
osb->sputn(osbuf,sb_p3-osbuf),sb_p3=osbuf;
}
}__cout;//声明用于输出的__cout
_GLIBCXX_END_NAMESPACE_VERSION
}
#endif