24

私は固定 NMEA センテンスで GPS ステータス エントリを解析しています。ただし、ロケールがコンマを小数点記号として定義しているシステムでは、atof関数はピリオドと小数部全体を無視します。

この問題に対処する最善の方法は何ですか? 必要に応じて、文字配列に格納された経度/緯度の文字列。

コード例:

m_longitude = atof((char *)pField); 

どこ

pField[] = "01000.3897"; 

Windows XP および CE 用にコンパイルされたクロスプラットフォーム プロジェクト。

ソリューションへのコメント:

受け入れられた回答はよりエレガントですが、この回答(およびコメント)も簡単な修正として知っておく価値があります

4

8 に答える 8

19

いつでも使用できます(モジュロエラーチェック):

#include <sstream>
...

float longitude = 0.0f;
std::istringstream istr(pField);

istr >> longitude;

標準の iostream は、デフォルトでグローバル ロケールを使用します (これは、従来の (US) ロケールに初期化する必要があります)。したがって、英語以外のプラットフォームで実行している場合でも、誰かが以前にグローバルロケールを別のものに変更していない限り、上記は一般的に機能するはずです。目的のロケールが確実に使用されるようにするには、特定のロケールを作成し、ストリームから読み取る前にそのロケールをストリームに「吹き込み」ます。

#include <sstream>
#include <locale>

...
float longitude = 0.0f;
std::istringstream istr(pField);

istr.imbue(std::locale("C"));
istr >> longitude;

補足として、私は通常、正規表現を使用して NMEA フィールドを検証し、フィールドのさまざまな部分をキャプチャとして抽出してから、上記の方法を使用してさまざまな部分を変換しました。NMEA 経度フィールドの小数点の前の部分は、実際には "DDDMM.mmm.." としてフォーマットされます。ここで、DDD は度、MM.mmm は分に対応します (ただし、既にご存知だと思います)。

于 2009-08-26T10:59:15.987 に答える
7

私が一度行った厄介な解決策は、sprintf()0.0f にして、出力から 2 番目の文字を取得することです。次に、入力文字列で「.」を置き換えます。そのキャラクターによって。これはコンマのケースを解決しますが、ロケールが他の小数点記号を定義した場合にも機能します。

于 2009-08-26T09:47:56.207 に答える
2

atof の前にsetlocale "C" を実行できず、後でロケールを復元できない理由はありますか? 多分私は質問を誤解しました...

于 2009-08-26T09:50:58.790 に答える
0

配列内のすべての文字を繰り返し処理し、数値以外の文字を文字と交換できます。これは、座標がフォーマット.されている限り機能するはずです。number-single_delimiter_character_-number

于 2009-08-26T09:53:01.190 に答える