文字列値が浮動小数点数として「資格がある」かどうかを判断する便利な方法を知っている人はいますか?
bool IsFloat( string MyString )
{
... etc ...
return ... // true if float; false otherwise
}
文字列値が浮動小数点数として「資格がある」かどうかを判断する便利な方法を知っている人はいますか?
bool IsFloat( string MyString )
{
... etc ...
return ... // true if float; false otherwise
}
Boostライブラリ関数を使用できない場合は、次のように独自のisFloat関数を作成できます。
#include <string>
#include <sstream>
bool isFloat( string myString ) {
std::istringstream iss(myString);
float f;
iss >> noskipws >> f; // noskipws considers leading whitespace invalid
// Check the entire string was consumed and if either failbit or badbit is set
return iss.eof() && !iss.fail();
}
Boost の lexical_cast が好きかもしれません ( http://www.boost.org/doc/libs/1_37_0/libs/conversion/lexical_cast.htmを参照)。
bool isFloat(const std::string &someString)
{
using boost::lexical_cast;
using boost::bad_lexical_cast;
try
{
boost::lexical_cast<float>(someString);
}
catch (bad_lexical_cast &)
{
return false;
}
return true;
}
istream を使用して Boost の必要性を回避できますが、率直に言って、Boost は除外するにはあまりにも優れています。
この回答に触発されて、文字列が浮動小数点数であるかどうかを確認するように関数を変更しました。ブーストを必要とせず、stringstreams failbit に依存しません。単純な解析です。
static bool isFloatNumber(const std::string& string){
std::string::const_iterator it = string.begin();
bool decimalPoint = false;
int minSize = 0;
if(string.size()>0 && (string[0] == '-' || string[0] == '+')){
it++;
minSize++;
}
while(it != string.end()){
if(*it == '.'){
if(!decimalPoint) decimalPoint = true;
else break;
}else if(!std::isdigit(*it) && ((*it!='f') || it+1 != string.end() || !decimalPoint)){
break;
}
++it;
}
return string.size()>minSize && it == string.end();
}
いえ
1
2.
3.10000
4.2f
-5.3f
+6.2f
この関数では float として正しく認識されます。
1.0.0
2f
2.0f1
無効なフロートの例です。X.XXf 形式の浮動小数点数を認識したくない場合は、次の条件を削除してください。
&& ((*it!='f') || it+1 != string.end() || !decimalPoint)
9 行目から。「.」のない数字を認識したくない場合は、float として (つまり、'1' ではなく、'1.'、'1.0'、'1.0f'... のみ)、最後の行を次のように変更できます。
return string.size()>minSize && it == string.end() && decimalPoint;
ただし、この「醜い関数」ではなく、boost の lexical_cast または stringstreams を使用するソリューションのいずれかを使用する十分な理由があります。しかし、浮動小数点数として正確に認識したい形式の種類をより詳細に制御できます(つまり、小数点以下の最大桁数...)。
[編集:最初の空白と末尾のナンセンスを禁止するように修正されました。]
#include <sstream>
bool isFloat(string s) {
istringstream iss(s);
float dummy;
iss >> noskipws >> dummy;
return iss && iss.eof(); // Result converted to bool
}
T
これを、の代わりに型でテンプレート化された関数に簡単に変換できますfloat
。これは基本的に、Boostのlexical_castが行うことです。
を使用した迅速で汚いソリューションstd::stof
:
bool isFloat(const std::string& s) {
try {
std::stof(s);
return true;
} catch(...) {
return false;
}
}
入力文字列に対して正規表現の一致を実行したいと思うでしょう。すべてのエッジケースをテストするのはかなり複雑かもしれません。
このサイトには良い情報があります。最後までスキップしたい場合は、次のように表示されます。
^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$
正規表現の構文を理解していれば、これは基本的に理にかなっています。
「 C++ で文字列を double に変換するにはどうすればよいですか?」で説明されている方法を使用できます。、およびをスローする代わりにconversion_error
、リターンfalse
(文字列が a を表していないことを示すfloat
)、およびtrue
それ以外の場合。
できることは、istringstreamを使用して、ストリーム操作の結果に基づいてtrue/falseを返すことです。このようなもの(警告-私はコードをコンパイルしていません、それはガイドラインのみです):
float potential_float_value;
std::istringstream could_be_a_float(MyString)
could_be_a_float >> potential_float_value;
return could_be_a_float.fail() ? false : true;
それは、信頼のレベル、必要なもの、および入力データの取得元によって異なります。データがユーザーからのものである場合は、インポートされたテーブル データと比較して、より注意する必要があります。インポートされたテーブル データでは、すべての項目が整数または浮動小数点のいずれかであり、区別する必要があるのはそれだけであることが既にわかっています。
たとえば、最も高速なバージョンの 1 つは、"." の存在を単純にチェックします。その中の「eE」。しかし、残りがすべて数字であるかどうかを調べたいと思うかもしれません。先頭の空白をスキップしますが、途中ではなく、単一の「.」を確認してください。「eE」など
したがって、q&d 高速ハックはおそらく、より洗練された regEx のような (呼び出すか自分でスキャンする) アプローチにつながるでしょう。しかし、結果がフロートのように見えても、マシンで実際に表現できることをどうやって知ることができますか (つまり、1.2345678901234567890e1234567890 を試してみてください)。もちろん、仮数/指数に「最大N」桁の正規表現を作成できますが、それはマシン/OS/コンパイラなど、特定のものである場合があります。
したがって、最終的には、基礎となるシステムの変換を呼び出して、何が得られるか (例外、無限大、または NAN) を確認する必要があります。
これは SO に関する一般的な質問です。提案については、この質問を参照してください(その質問では string->int について説明していますが、アプローチは同じです)。
注: 文字列を変換できるかどうかを知るには、基本的に変換を行って、オーバー/アンダーフローなどをチェックする必要があります。
atofを使用して を特別に処理することもできますが、それ0.0
は特に良い解決策とは言えません。
atof
関数も同様であるため、先頭の空白を無視したくなるでしょう。
この関数は、最初の非空白文字が見つかるまで、必要な数の空白文字を最初に破棄します。次に、この文字から始めて、浮動小数点リテラルの構文に似た構文に従って有効なできるだけ多くの文字を取得し、それらを数値として解釈します。最後の有効な文字の後の文字列の残りは無視され、この関数の動作には影響しません。
したがって、これを一致させるには、次のようにします。
bool isFloat(string s)
{
istringstream iss(s);
float dummy;
iss >> skipws >> dummy;
return (iss && iss.eof() ); // Result converted to bool
}