【问题标题】:Print integer with thousands and millions separator打印带有千和百万分隔符的整数
【发布时间】:2013-07-06 00:11:29
【问题描述】:

有一个关于打印带有千/百万分隔符的整数的问题。

我有一个文本文件,其中包含国家、城市、总人口。

我必须阅读文件,并按国家/地区排序。如果国家是平等的,我必须按人口降序排序。

文本文件是这样的:

澳大利亚............悉尼......10.123.456

巴西…………圣保罗……7.123.345

我将所有 3 个读入一个单独的字符串。然后我删除所有“。”在人口字符串中。然后我使用 atoi() 将人口字符串转换为整数。

如果国家/地区相等,现在我可以按人口排序。这种排序工作正常。

到目前为止一切顺利。但我需要在人口打印中加入千/百万分隔符。

如果我使用字符串,则使用“。”对于人口,排序不能正常工作。 它的排序如下:

x........x......1.123456

x........x......10.123.456

x........x......2.123.232

它必须看起来像:

澳大利亚............悉尼......10.123.456

澳大利亚........布里斯班.......8.123.456

有没有办法通过再次在 int 中添加分隔符来操作打印?

提前致谢

【问题讨论】:

  • 使用具有该分隔符的语言环境? (有关更多信息,请参阅 C++ localization functionality。)
  • 当然它不会正确排序...您将这些数字视为字符串,这意味着10 小于7,因为17 之前.您应该将数字保留为内部整数,并且仅在实际进行输出时将它们转换为格式化版本。
  • 人口是整数。我只是使用字符串读入,然后我删除所有“。”并将它们转换为 int。

标签: c++ fstream separator


【解决方案1】:

imbue() 具有所需分隔符的locale 的输出流。例如:

#include <iostream>
#include <locale>

int main()
{
    // imbue the output stream with a locale.
    int i = 45749785;
    std::cout << i << "\n";

    std::cout.imbue(std::locale(""));
    std::cout << i << "\n";
}

在我的机器上输出(和online demo):

45749785 45,749,785

正如James Kanze 评论和回答的那样,输入流也可以在不手动修改输入的情况下读取分离的int 值。


请参阅 Stroustrop 的 Appendix D: Locales 了解语言环境的详细概述。

【讨论】:

  • 他还应该在输入流上使用相同的本地,这样他就不必手动去除分隔符。 (并且语言环境"" 是否会这样做会有很大差异。在Unix 机器上,除非用户设置了至少一个LC_... 环境变量,否则"" 将给出“Posix”语言环境,这与“C”语言环境,不使用千位分隔符。另一方面,如果用户将其设置为“fr_FR”,那么千位分隔符将是'.',而不是','
  • @JamesKanze,代码说明了如何imbue() 流,我接受用户区域设置会有所不同。 OP 有责任确定适当的语言环境(AFAIK 这些没有标准名称)。同意输入流,谢谢。
  • 现在可以使用了,谢谢各位。我现在使用:locale::global(locale("German_germany")); std::locale mylocale("");使用 2 个语言环境会有问题吗?如果我只使用德语,我没有分隔符。
  • @d0zer:使用多个语言环境的唯一真正问题(我遇到过)是跟踪它们(您已将其应用于什么)。
  • @d0zer 当您执行locale::global( locale( "German_germany" ) ) 时,您正在更改全局本地;构建新流时默认使用的那个。 (默认情况下它很有可能影响std::cout。这就是为什么你总是在程序开始时灌输标准流。)至于在同一个字符串上多次更改语言环境:如果两者都有非常严重的限制当地人有不同的codecvt。否则应该没有问题。
【解决方案2】:

使用支持所需分隔符的语言环境来读取 文件(这样您就可以将值读取为整数),以及 相同的语言环境来写入数据。

请注意,您可能没有这样的语言环境,或者如果您 做,你可能不知道它的名字(并且使用命名的语言环境可能 改变其他你不想改变的东西);在我的 机器,imbueing 和 "" 的行为不同 编译器(或者可能是我从中调用它的 shell)——你 如果您有严格的格式,则永远不要使用语言环境"" 要求。 (使用语言环境"" 是针对您的情况 想要依赖于用户环境的格式 规格。)

在这种情况下,最好明确地提供本地:

class MyNumPunct : public std::numpunct<char>
{
protected:
    virtual char do_thousands_sep() const { return ','; }
    virtual std::string do_grouping() const { return "\03"; }
};

int
main()
{
    std::cout.imbue( std::locale( std::locale::classic(), new MyNumPunct ) );
    std::cout << 123456789 << std::endl;
    return 0;
}

当然,您也希望使用此语言环境进行输入。 (此代码将为您提供 "C" 语言环境,只有 分组已更改。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-16
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 2014-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多