Проблемы c++ iomanip lib setfill и setw



Мой Код:



#include <iostream>
#include <iomanip>

using namespace std;

int main () {
int time;
int honolulu, seattle, london, moscow, hongkong, auckland;

cout << "What is the current time in Philadelphia? ";
cin >> time;

honolulu = (time+2400-600)%2400;
seattle = (time+2400-300)%2400;
london = (time+2400+500)%2400;
moscow = (time+2400+800)%2400;
hongkong = (time+2400+1200)%2400;
auckland = (time+2400+1700)%2400;

cout << endl << "Current times in other cities: " << endl;
cout << setw (12) << left << "Honolulu:";
cout << setw (4) << setfill('0') << honolulu << endl;
cout << setw (12) << left << "Seattle:";
cout << setw (4) << setfill('0') << seattle << endl;
cout << setw (12) << left << "London:";
cout << setw (4) << setfill('0') << london << endl;
cout << setw (12) << left << "Moscow:";
cout << setw (4) << setfill('0') << moscow << endl;
cout << setw (12) << left << "Hong Kong:";
cout << setw (4) << setfill('0') << hongkong << endl;
cout << setw (12) << left << "Auckland:";
cout << setw (4) << setfill('0') << auckland << endl;

return 0;
}


Требуемый Выход:



What is the current time in Philadelphia? 0415    

Current times in other cities:
Honolulu: 2215
Seattle: 1150
London: 9150
Moscow: 1215
Hong Kong: 1615
Auckland: 2115


Мои выходные данные:



What is the current time in Philadelphia? 0415    

Current times in other cities:
Honolulu: 2215
Seattle:00001150
London:000009150
Moscow:000001215
Hong Kong:001615
Auckland:0002115


Что я делаю не так? Первая строка вывода, Honolulu: 2215, является правильной. Но в следующих строках есть ведущие нули. Я не понимаю, почему это происходит? Есть ли проблема с моим кодом или я неправильно понимаю, как работают функции setfill и setw?

727   3  

3 ответов:

Как упоминалось в других комментариях, многие манипуляторы ввода-вывода являются "липкими". Лично я предпочитаю решать такого рода задачи с помощью RAII:

class stream_format_raii {
public:
   stream_format_raii(std::ostream &stream)
      : stream_(stream)
      , state_(NULL) {
      state_.copyfmt(stream_);
   }

   ~stream_format_raii() {
      stream_.copyfmt(state_);
   }
public:
   std::ostream &stream_;
   std::ios  state_;
};

Этот класс выполняет резервное копирование формата текущего потока при построении и его восстановление при разрушении.

Вы можете использовать его следующим образом:

void printCity(std::ostream &os, const std::string name, int time) {
   stream_format_raii back(os);
   os << std::setw(12) << std::left << (name + ":");
   os << std::setw(4) << std::setfill('0') << time;
}


int main() {
   // Same as before
   printCity(std::cout, "Honolulu", honolulu);
   // Same as before
}

Символ заливки является "липким", поэтому он остается в силе до тех пор, пока вы его не измените.

В вашем случае вы хотите 0 в качестве заполнения для числовых полей, но пробел в качестве заполнения для символьных полей, поэтому вам придется установить это явно, что-то вроде этого:

cout << setfill(' ') << setw (12) << left << "Seattle:";

Многие объекты iomanip являются "липкими", то есть они прилипают к потоку и влияют на последующие строки.

Когда у вас есть это:

cout << setw (12) << left << "Seattle:";
cout << setw (4) << setfill('0') << seattle << endl;

, который собирается оставить setfill активным для следующей строки. Поэтому вы могли бы вместо этого предпочесть

cout << setw (12) << setfill(' ') << left << "Seattle:";
cout << setw (4) << setfill('0') << seattle << endl;

Comments

    Ничего не найдено.