2013-10-05 58 views
1

我想讀取RINEX文件中多行數字。文件編號看起來像:C++讀取兩個數字但沒有空格,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

感謝

回答

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的臨時實例以檢索值。

注意:可能需要額外的錯誤處理。

+0

如何測試此方法,如果它只有3位小數。現在發生了什麼,如果我把它的單詞123.456拋出,所以我想基本上將它分解爲if(if>(word> 3 decimals))else – user2840470

0

如果你不想用繩子亂,你可以分別讀取積分和小數部分,得到你需要這樣的數據: 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個位數更長)

1

浮動點默認的輸入格式有小數點後面將讀取儘可能多的數字。但是,可以通過使用自定義的std::num_get<char>構面並安裝合適的區域設置來更改用於解析值的函數。下面是如何可以粗略地看(我目前不能方便地測試的代碼):

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