2016-01-13 42 views
3

我的代码:C++了iomanip LIB setfill和运输及工务局局长问题

#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是正确的。但接下来的几行有前导零。我不明白为什么会发生这种情况?我的代码有问题吗?或者我误解了函数setfillsetw的工作原理?

+0

一些操纵只对下一个输出,有些原地踏步的所有输出。 'std :: setfill'将为* all *后面的输出设置填充字符。' –

回答

2

正如其他评论中提到的,许多I/O操纵器都是“粘性”的。 我个人比较喜欢使用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 
} 
4

许多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; 
4

填充字符是“粘”,所以它一直有效,直到你改变它。

在你的情况,你想0作为填充在数字领域,但空间填充的字符字段,所以你必须设定明确,这样的事情:

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