简体   繁体   English

C++ 中的 cout 问题

[英]Problems with cout in C++

To start, I want to show you my code below.首先,我想在下面向您展示我的代码。

#include<iostream>

int main()
{
    float num = 3;
    std::ios_base::fmtflags initial;
    initial = std::cout.setf(std::ios_base::fixed);
    std::cout.setf(initial);
    std::cout<<num;
}

The output is 3.000000. output 为 3.000000。 With only first and last lines output is 3. My book says that "The setf() method returns a copy of all the formatting settings in effect before the call was made. std::ios_base::fmtflags is a fancy name for the type needed to store this information. So the assignment to initial stores the settings that were in place before the setf function was called. The initial variable can then be used as an argument to setf() to reset all the formatting settings to this original value."只有第一行和最后一行 output 是 3。我的书说“setf() 方法返回调用之前所有有效格式设置的副本。std::ios_base::fmtflags 是该类型的一个花哨名称需要存储此信息。因此,对 initial 的赋值存储了调用 setf function 之前的设置。然后可以将初始变量用作 setf() 的参数,以将所有格式设置重置为该原始值。 " But as you can see, it doesn't work.但正如你所见,它不起作用。 What's the issue?有什么问题?

From std::ios_base::setf :std::ios_base::setf

fmtflags setf( fmtflags flags ); (1) (1)
fmtflags setf( fmtflags flags, fmtflags mask ); (2) (2)
Sets the formatting flags to specified settings.将格式化标志设置为指定的设置。

  1. Sets the formatting flags identified by flags.设置由标志标识的格式化标志。 Effectively the following operation is performed fl = fl |有效地执行了以下操作fl = fl | flags where fl defines the state of internal formatting flags. flags其中 fl 定义了内部格式化标志的 state。
  2. Clears the formatting flags under mask, and sets the cleared flags to those specified by flags.清除掩码下的格式化标志,并将清除的标志设置为标志指定的标志。 Effectively the following operation is performed fl = (fl & ~mask) |有效地执行了以下操作 fl = (fl & ~mask) | (flags & mask) where fl defines the state of internal formatting flags. (标志和掩码)其中 fl 定义了内部格式化标志的 state。

(Emphasize is mine.) (强调是我的。)

So, std::ios::setf() is a good choice to set individual flags but it's a bad choice to set all flags at once.因此, std::ios::setf()是设置单个标志的好选择,但一次设置所有标志是一个糟糕的选择。

For this, std::ios_base::flags is the right tool:为此, std::ios_base::flags是正确的工具:

fmtflags flags() const; (1) (1)
fmtflags flags( fmtflags flags ); (2) (2)
Manages format flags.管理格式标志。

  1. returns current formatting setting返回当前格式设置

  2. replaces current settings with given ones.用给定的设置替换当前设置。

Sample:样本:

#include<iostream>

int main()
{
    float num = 3;
    std::cout<<num<<'\n';
    std::ios_base::fmtflags initial;
    initial = std::cout.setf(std::ios_base::fixed);
    std::cout.flags(initial); // <-- the fix
    std::cout<<num<<'\n';
}

Output: Output:

3
3

Live Demo on colirucoliru 现场演示

Some of the format flags are mutually exclusive .一些格式标志是互斥的

For example, std::ios_base::left can not be used together std::ios_base::right .例如, std::ios_base::left不能一起使用std::ios_base::right std::ios_base::fixed is an exclusive flags also. std::ios_base::fixed也是一个独占标志。 It can not be used with std::ios_base::scientific .它不能与std::ios_base::scientific一起使用。 To exclusively set a format flag, std::ios_base::setf() takes additional bit group flag as its second parameter.要独占设置格式标志, std::ios_base::setf()将附加位组标志作为其第二个参数。 You can then set a format flag correctly.然后,您可以正确设置格式标志。 std::ios_base::fixed is a group of std::ios_base::floatfield and you should set it as its second parameter when calling setf(). std::ios_base::fixed是一组std::ios_base::floatfield ,你应该在调用 setf() 时将它设置为它的第二个参数。

#include <iostream>

int main(void)
{
    float num = 3;

    std::ios_base::fmtflags initial;
    initial = std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield);
    std::cout.setf(initial, std::ios_base::floatfield);

    std::cout << num;  // 3 printed on VS2019

    return 0;
}

You can also simply use io manipulators .您也可以简单地使用io 机械手 (It's also more readable code): (它也是更具可读性的代码):

#include<iostream>

int main()
{
    float num = 3;
    
    std::cout<< std::fixed;
    
    std::cout << num<<'\n';
    std::cout<<num<<'\n';
    
    std::cout << std::scientific;

    std::cout << num<<'\n';
    std::cout<<num<<'\n';
    
    std::cout << std::defaultfloat;

    std::cout << num<<'\n';
    std::cout<<num<<'\n';
    
    

} }

Live on coliru以大肠杆菌为生

Output: Output:

3.000000
3.000000
3.000000e+00
3.000000e+00
3
3

setf is used to set a specific format flag. setf用于设置特定的格式标志。 So it does not reset the set fixed flag when you call std::cout.setf(initial);因此,当您调用std::cout.setf(initial);时,它不会重置设置的fixed标志; You probably want to use the flags function instead:您可能想改用标志function :

#include <iostream>

int main()
{
    const double num = 3.0;
    std::cout << num << '\n';
    const auto initial_flags = std::cout.flags(std::ios_base::fixed);
    std::cout << num << '\n';
    std::cout.flags(initial_flags);
    std::cout << num << '\n';
}

Output: Output:

3
3.000000
3

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

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