【问题标题】:C++ read in two numbers but no spaces, RINEX fileC++ 读取两个数字但没有空格,RINEX 文件
【发布时间】:2013-10-12 15:18:19
【问题描述】:

我正在尝试从 RINEX 文件的行中读取多个数字。文件编号类似于:

12345.67890

但是,由于 RINEX 格式化,12345.6789 表示测量值,而小数点末尾的 0 实际上表示其他值。我正在使用基本的阅读方式:

Rinexfile>>double_temp;

我得到 double_temp=12345.67890 我想做的地方

Rinexfile>>double_temp>>int_temp;

并且有 double_temp=12345.6789 和 int_temp=0。格式始终相同,即 4 位小数属于双精度,然后是一个 int,我使用的是 VS2010

谢谢

【问题讨论】:

    标签: c++ file-io int double filestream


    【解决方案1】:

    您需要更复杂的方法:

    std::string word;
    Rinexfile >> word;
    std::size_t dot_pos = str.find('.');
    if (dot_pos != std::string::npos) {
        std::string doublePart = word.substr(0, dot_pos + 1 + 4);  // 4 decimals
        std::string intPart = word.substr(dot_pos + 1 + 4);
        std::istringstream is(doublePart), is2(intPart);
        is >> double_temp;
        is2 >> int_temp;
    }
    

    这会读取单个std::string 形式的输入并将其分为两部分:doublePart 是一个包含'.' 符号和其后的4 个字母的字符串。 intPart 是这个词的其余部分。构造 std::istringstream 的临时实例以检索值。

    注意:可能需要额外的错误处理。

    【讨论】:

    • 如果这个方法只有 3 位小数,我怎么能测试它。如果我将单词 123.456 抛出,现在会发生什么,所以我想要基本上将其分解为 if, if(word>3 decimals) else
    【解决方案2】:

    浮点的默认输入格式将读取小数点后的位数。但是,可以通过使用自定义std::num_get<char> facet 并安装合适的语言环境来更改用于解析值的函数。这是大致的样子(目前我无法轻松测试代码):

    #include <locale>
    #include <cstdlib>
    #include <cctype>
    
    struct num_get
        : std::num_get<char>
    {
        iter_type do_get(iter_type it, iter_type end, std::ios_base& fmt,
                         std::ios_base::iostate& err, double& value) const {
            char buf[64];
            char* to(buf), to_end(buf + 63);
            for (; it != end && to != to_end
                 && std::isdigit(static_cast<unsigned char>(*it)); ++it, ++to) {
                *to = *it;
            }
            if (it != end && *it == '.') {
                *to = *it;
                ++it;
                ++to;
            }
            to_end = to_end - to < 4? to_end - to: to + 4;
            for (; it != end && to != to_end
                 && std::isdigit(static_cast<unsigned char>(*it)); ++it, ++to) {
                *to = *it;
            }
            *to = 0;
            if (std::strtod(buf, 0, &value) != to) {
                err |= std::ios_base::failbit;
            }
            return it;
        }
    };
    

    使用此解码器(不过,它可能需要进行更多的错误检查),您只需设置您的流,然后正常读取:

    in.imbue(std::locale(std::locale(), new num_get));
    double dval;
    int    ival;
    if (in >> dval >> ival) {
        std::cout << "read dval=" << dval << " ival=" << ival << '\n';
    }
    

    【讨论】:

      【解决方案3】:

      如果你不想弄乱字符串,你可以分别读取整数和小数部分,并得到你需要的数据,如下所示: int i, d;

      cin >> i;
      cin.get();  // skip decimal point
      cin >> d;
      
      double value = i + (d / 10) / 10000.0;
      int something_else = d % 10;
      
      cout << setprecision(4) << fixed << value << endl << something_else;
      

      (如果“其他”可以长于 1 位,它将不起作用)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-11-09
        • 1970-01-01
        • 1970-01-01
        • 2020-03-18
        • 1970-01-01
        • 2014-05-02
        • 1970-01-01
        相关资源
        最近更新 更多