2012-03-12 10 views
0

C++では、Boostライブラリを使用しない方が、std :: string strに数字または数字の後に '%'記号が含まれていることを確認するにはどうすればよいですか?これらの2つのケースに属していない場合は、エラーを発行する必要があります。すべての桁の数値または数字とパーセント記号になる文字列を解析する

+0

は、変異体の多くを見るために解決策を求めて学び、最高のを選択しようとしました。 – Narek

答えて

1
#include <iostream> 
#include <string> 
#include <algorithm> 
#include <ctype.h> 
bool is_a_bad_char(char c) { 
    return !(isdigit(c) || (c=='%')); 
} 

int main() { 
    std::string str = "123123%4141219"; 
    if (std::find_if(str.begin(), str.end(), is_a_bad_char) != str.end()) { 
    std::cout << "error" << std::endl; 
    return 1; 
    } 
    return 0; 
} 
0
  1. find_first_not_of%
  2. 上記戻りnpos場合は、チェック最後の文字が%です。
0

あまりC++ - っぽいが、このようなものはそれを行うだろう:

#include <cstdlib> 
#include <cstring> 

bool checkformat(const std::string &s) { 
    const char *begin = s.c_str(); 
    char *end; 
    double val = std::strtod(begin, &end); 
    if (end == begin) return false; 
    if (*end == '%') ++end; 
    return (end - begin == s.size()); 
} 

あなたが最初の空白文字列を受け入れるようにしたくないので、もし、strtodは初期の空白をスキップすることに注意してくださいそれを別に拒否する必要があります。また"NAN""INF""INFINITY"(すべて大文字と小文字を区別しない)、及び+又は-が先行それらのもののそれぞれを受け入れ、"NAN"任意選択の場合には、それが表すれる NaN値を示すために、いくつかの実装で定義された文字に続きます。おそらく "INF"は数字ですが、 "NAN"は定義されていないので、val != valの場合はfalseを返し、無限をチェックすることもできます。

[編集:私はジェームズが下に提起した問題を修正したと思いますが、" "" %"は依然として論争中です。そして、彼はミックスにオーバーフローを加えました。彼の答えと私の間に、あなたのアイデアを得る必要があります - 最初にあなたがして、各エッジケースを扱い、それをコーディングする方法を決定]

+0

最初の文字列が "1 \ 0x"のような場合はどうでしょうか?私は '* pend == '%''をインクリメントした後に '* pend - begin == s.size()'をチェックします。あなたのコードも私のどちらも '' ''や ''% "'のようなものを正しく処理しません。私は 'errno'を' 0'に設定してから、それをテストしなければならないと思います。 –

+0

また、コードにバグがあると思います。あなたは 'char * pend;'を使い、 'strtod'に'&pend'を渡します( '* pend ' pend'、 '** pend'を使って' ** pend')を実行します。また、パラメータに '&s'の代わりに' s& 'を打ち込みます。 –

+0

@ジェームズ:埋め込まれたヌルスについて合意した。 'strtod'は、変換が行われない場合、そのパラメタ' str'を '* endptr'に格納することになっています。対象シーケンスの最初の文字へのポインタではないので、' '' 'の問題は何ですか? '* pend'は' '' '、' false'を返します。私はおそらくこれをテストしたはずです。 –

1

最も簡単な解決策はstrtol またはstrtod、依存を使用して文字列を(変換することはおそらくです。あなたが期待している数字のタイプについて)、次の文字を で見てください。ような何か:

は(エラー処理を修正するために編集):

bool 
isNumberOrPercent(std::string const& value) 
{ 
    char const* end; 
    errno = 0; 
    strtod(value.c_str(), &end); 
    return errno == 0 
     && (*end = '%' ? end + 1 : end) - value.c_str() == value.size(); 
} 
+0

また、 'strtod'は、変換が失敗した場合(over/underflow用ではあるが)、' errno'を設定する*必須ではないことにも注意してください。だから面倒なことに、あなたの関数は空の文字列を渡すと真を返すことになります。 –

+0

よろしくお願いします。それは標準(IMHO)の重大なエラーです。 (あなたが書いたものを読んだときに標準が愚かなことをしたとは信じられませんでしたが、明らかにそれがあります。)したがって、 'end == value.c_str()'の追加テストが必要です。 –

+0

私はYHOに同意します! 'strtod'には、変換中の問題を示す2つの方法があり、どちらもすべてのエラーケースをカバーしません(オーバーフローがエラーとみなされる場合)。これは弱いです。 –

関連する問題