Изучение C ++ с помощью Брюса Экеля «Мышление в C ++». Застрял в упражнении 05 главы «Iostreams»:
Мы знаем, что setw () учитывает минимум символов для чтения, но что, если вы хотите прочитать
максимум? Напишите эффектор, который позволяет пользователю указать максимальное количество символов для
извлечь. Пусть ваш эффектор также работает для вывода таким образом, что поля вывода усекаются, если
необходимо, чтобы оставаться в пределах ширины.
Я понимаю, как создавать манипуляторы как без параметра, так и с параметром (который в терминологии книги называется эффектором). Но не понимаю, как ограничить максимальное количество символов для извлечения. std::ios_base::width
указывает минимальное количество символов
Должен ли я сделать некоторые трюки с основным streambuf
объект?
Это не идеальное решение (но я не могу придумать другого пути в данный момент, не читая библиотеку 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, так что если он передается в функцию, он все равно ведет себя как поток (хотя он теряет свойство max width).
class MaxFieldWithStream
{
std::ostream& printTruncatedData(std::string& value);};
operator st::ostream&() const { return BLABLAVLA;}
};
#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;
}