2014-09-17 7 views
2

Рассмотрим следующий код:Неожиданное поведение станд :: setw при использовании станд :: stringstream

std::string n("123456"); 


std::stringstream ss; 
ss << std::setw(3) << n; 
std::cout << ss.str() << " | " << (ss.fail() ? "True" : "False") << std::endl; 

Почему это распечатывают

123456 | False 

вместо

123 | False 
+3

Я думаю, вы, возможно, непонятый 'setw': http://en.cppreference.com/w/ cpp/io/manip/setw – taocp

+0

Значение «установки ширины» может быть неясным, вот объяснение: http://en.cppreference.com/w/cpp/io/ios_base/width – jliv902

ответ

2

Эффекты модификатора ширины обрабатываются по-разному с помощью разных форматировщиков. В выражении ss << std::setw(3) << n, где n имеет тип std:string, вы используете operator<<(ostream&, const std::string&), который выполняет следующие действия (от cppreference):

а) Если str.size() не меньше, чем os.width(), использует диапазон [str.begin(), str.end()) как есть

В вашем случае, это str.size()6 и ss.width() является 3, так что вся строка выводится

0

Задача

Его идеальное поведение: setw() устанавливает минимальную ширину поля. Если ваш выход превышает эту длину, он написан на всю длину. Кстати, ширина будет применяться ко всем следующим выходам, пока вы не измените ее снова.

Как только о форматировании и как ostream не имеет личного вкуса о плохом alignemnt, fail() всегда возвращает ложь ;-)

Решение

Если выход только строки, у вас есть все сила строки expression:

ss << setw(3) << n.substr(0,3) ; // set mini and maxi. 

Если у вас есть много такого форматирования, а также с типами арифметических, вы могли бы рассмотреть возможность написания небольшого Ada PTER как следующее:

template <class T> 
string mfixed(ostream& os, T o, int n) 
{ 
    stringstream ss; 
    ss.copyfmt(os); // copy ALL format flags of ostream 
    ss << setw(n)<< o; // set the fixed length and ouput 
    return ss.str().substr(0, n); // truncate 
} 

Вы можете использовать его очень гибко в коде:

ss << mfixed(ss, n, 3) 
    << " " << mfixed(ss, 25, 4) << " " << mfixed(ss, 100000, 3) 
    << " " << setprecision(2) << mfixed(ss, 1.0/3.0, 4); 
Смежные вопросы