简体   繁体   English

C ++ Iomanip lib setfill和setw问题

[英]C++ Iomanip lib setfill and setw issues

My Code: 我的代码:

#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;
}

Required Output : 要求输出:

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

My output : 我的输出:

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

What am I doing wrong? 我究竟做错了什么? The first line of output, Honolulu: 2215 , is correct. 第一线产出, Honolulu: 2215 ,是正确的。 But the next lines have leading zeroes. 但接下来的行有前导零。 I do not understand why this is happening? 我不明白为什么会这样? Is there a problem with my code or am I misunderstanding how the functions setfill and setw work? 我的代码有问题,还是我误解了函数setfillsetw是如何工作的?

Many of the iomanip objects are "sticky", that is, they stick to the stream and affect subsequent lines. 许多iomanip对象都是“粘性的”,也就是说,它们会粘在流上并影响后续行。

When you have this: 当你有这个:

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

that is going to leave the setfill active for the next line. setfill下一行的setfill活动状态。 So you might instead prefer 所以你可能更喜欢

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

The fill character is "sticky", so it remains in effect until you change it. 填充字符是“粘性”,因此在您更改之前它仍然有效。

In your case, you want 0 as the fill for the numeric fields, but space as the fill for the character fields, so you'll have to set that explicitly, something like this: 在您的情况下,您希望0作为数字字段的填充,但空格作为字符字段的填充,因此您必须明确设置,如下所示:

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

As mentioned in other comments many of I/O manipulators are "sticky". 正如其他评论中提到的,许多I / O操纵器都是“粘性的”。 I personally prefer to solve this kind of problem using RAII : 我个人更喜欢使用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_;
};

That this class does is backing up your current stream's format upon constructing and setting it back upon destructing. 这个类所做的是在构造时备份当前流的格式,并在破坏时将其设置回来。

You can use it this way: 你可以这样使用它:

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM