0

在 Bruce Eckel “Thinking in C++”的帮助下学习 C++。陷入“Iostreams”一章的练习 05:

练习文本

我们知道 setw( ) 允许读取最少的字符,但是如果您想读取最多的字符怎么办?编写一个效应器,允许用户指定要提取的最大字符数。让您的效应器也用于输出,如果需要,输出字段会被截断,以保持在宽度限制内。

我了解如何创建不带参数和带参数的操纵器(在本书术语中称为效应器)。但是不明白如何限制要提取的最大字符数。std::ios_base::width指定最小字符数。

我应该对底层streambuf对象做一些技巧吗?

4

2 回答 2

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;
}
于 2012-12-17T08:13:21.980 回答
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;}
};
于 2012-11-30T14:58:50.003 回答