在Bruce Eckel的帮助下学习C ++“用C ++思考”。被困在“Iostreams”一章的练习05中:
我们知道setw()允许读入最少的字符,但如果你想阅读一个字符怎么办? 最大值?编写一个效应器,允许用户指定最多的字符数 提取。让你的效应器也适用于输出,输出字段被截断,if 必要的,保持在宽度范围内。
我理解如何在没有参数的情况下创建操纵器(在书中术语中称为效应器)。但是不明白如何限制要提取的最大字符数。 std::ios_base::width
指定最小字符数。
Shoud我用底层streambuf
对象做了一些技巧?
答案 0 :(得分:2)
#include <iostream>
#include <iomanip>
#include <string>
#include <cstring>
using namespace std;
class fixW{
char* chrP;
char str[1024];
size_t Max;
public:
fixW(char* p,size_t m=25):chrP(p),Max(m){}
friend istream& operator >>(istream& is,fixW fw){
is >>fw.str;
size_t n=strlen(fw.str);
cout <<" n= "<<n << endl;
if(n>=25){
fw.str[fw.Max]='\0';
}
strcpy(fw.chrP,fw.str);
return is;
}
friend ostream& operator<<(ostream& os, fixW fw){
for(size_t i= 0; i<fw.Max; ++i){
fw.str[i] = fw.chrP[i];
}
fw.str[fw.Max]='\0';
return os <<fw.str;
}
};
int main(){
char s[80];
cin >> fixW(s,25);
cout << s << endl;
cout << fixW(s,10)<<endl;
cout << s <<endl;
return 0;
}
答案 1 :(得分:1)
它不是一个完美的解决方案(但是如果不阅读iostream库,我现在想不到另一种方式)。
说你操纵者是:
class MaxFieldSize {/*STUFF*/};
当您编写流操作符时,您会编写一个稍微有点时髦的操作符,它不返回实际的流(而是返回一个带有包装器的流)。
MaxFieldWdithStream operator<<(std::ostream&, MaxFieldSize const& manip);
现在重载此类的所有流操作符以在返回普通流对象之前截断它们的输入。
class MaxFieldWithStream { std::ostream& printTruncatedData(std::string& value);};
然后您只需要通用重载:
template<typename T>
std::ostream& operator<<(MaxFieldWithStream& mfwstream, T const& value)
{
std::stringstream trunStream;
trunStream << value;
return mfwstream.printTruncatedData(trunStream.substr(0, mfwstream.widthNeeded));
}
// You will probably need another overload for io-manipulators.
我还会添加一个转换运算符,它自动将MaxFieldWithStream转换为std :: iostream,这样如果它被传递给一个函数,它仍然表现得像一个流(虽然它会松开它的最大宽度属性)。
class MaxFieldWithStream
{
std::ostream& printTruncatedData(std::string& value);};
operator st::ostream&() const { return BLABLAVLA;}
};