web-dev-qa-db-ja.com

入力がC ++の数値または文字列かどうかを確認する

Input(answer3)が数値であるか文字列であるかを確認するために次のコードを書きました。数値でない場合は「Enter Numbers Only」を返す必要がありますが、数値でも同じを返します。私に解決策を提案してください。

#include <iostream>
#include <string>
#include <typeinfo>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

using namespace std; 
int main ()
{

string ques1= "Client's Name :";
string ques2 = "Client's Address :";
string ques3 = "Mobile Number :";

char answer1 [80];
string answer2;
int answer3;

     cout<<ques1<<endl;    
     cin>>answer1;      

     cout<<ques2<<endl;    
     cin>>answer2; 

     cout<<ques3<<endl;
     cin>>answer3;

       if (isdigit(answer3))
       {
              cout<<"Correct"<<endl;     

              }

        else
        {
          cout<<"Enter Numbers Only"<<endl;  

            }

 system("pause>null");
 return 0;  

}
8
WESTRUK

これを行うには、regexを使用できます。

_#include <regex>

bool isNumber(std::string x){
    std::regex e ("^-?\\d+");
    if (std::regex_match (x,e)) return true;
    else return false;}
_

isNumber()を任意のタイプの入力を取ることができるジェネリック関数にしたい場合:

_#include <regex>
#include <sstream>

template<typename T>
bool isNumber(T x){
    std::string s;
    std::regex e ("^-?\\d+");
    std::stringstream ss; 
    ss << x;
    ss >>s;
    if (std::regex_match (s,e)) return true;
    else return false;}
_

上記のisNumber()関数は整数のみをチェックし、精度のあるdoubleまたはfloat値(ドット_._を含む)はtrueを返しません。精度も必要な場合は、regex行を次のように変更します。

_std::regex e ("^-?\\d*\\.?\\d+");
_

より効率的なソリューションが必要な場合は、 これ を参照してください。

7
Jahid

C++ 98を使用している場合は、stringstreams#include <sstream>):

std::string s = "1234798797";
std::istringstream iss(s);

int num = 0;

if (!(iss >> num).fail()) {
    std::cout << num << std::endl;
}
else {
    std::cerr << "There was a problem converting the string to an integer!" << std::endl;
}

ブーストを利用できる場合lexical_cast#include <boost/lexical_cast.hpp>):

std::string s = "1234798797";
int num = boost::lexical_cast<int>(si);//num is 1234798797
std::cout << num << std::endl;

C++ 11が利用できる場合、組み込みのstd::stoi関数 から<string>

std::string s = "1234798797";
int mynum = std::stoi(s);
std::cout << mynum << std::endl;

出力:

1234798797
7
jrd1

関数isdigit()は、数字(0,1、...、9)のみをテストするために使用されます

この関数を使用して数値を確認します

bool is_number(const std::string& s)
{
    std::string::const_iterator it = s.begin();
    while (it != s.end() && std::isdigit(*it)) ++it;
    return !s.empty() && it == s.end();
}
3
Chethan N

strtod を使用した別の回答:

_bool isNumber(const std::string& s){
   if(s.empty() || std::isspace(s[0]) || std::isalpha(s[0])) return false ;
   char * p ;
   strtod(s.c_str(), &p) ;
   return (*p == 0) ;
}
_

任意のタイプのパラメーターを処理できるようにするには、テンプレートを使用します。

_#include <sstream>

template<typename T>
bool isNumber(T x){
   std::string s;
   std::stringstream ss; 
   ss << x;
   ss >>s;
   if(s.empty() || std::isspace(s[0]) || std::isalpha(s[0])) return false ;
   char * p ;
   strtod(s.c_str(), &p) ;
   return (*p == 0) ;
}
_

注:

  1. 空白はfalseを返します。
  2. NANINFは、falseを返します(正確には、有効な指数以外の文字はすべてfalseを返します)。 nanおよびinfを許可する場合は、|| std::isalpha(s[0])部分を削除します。
  3. 科学的形式が許可されています。つまり、1e + 12はtrueを返します。
  4. Double/floatまたはintegerはtrueを返します。
  5. これは regex answer よりも効率的です。 (正規表現は重い)。
1
Jahid

isdigitへの入力は整数値です。ただし、値が「0」〜「9」に対応する場合にのみtrue(ゼロ以外)を返します。それらを整数値に変換すると、48〜57になります。他のすべての値の場合、isdigitはfalse(ゼロ)を返します。

チェックロジックを変更して、整数を取得したかどうかを確認できます。

if ( cin.fail() )
{
   cout<<"Correct"<<endl;     
}
else
{
   cout<<"Enter Numbers Only"<<endl;  
}
1
R Sahu

これはやや古い質問ですが、自分のコードで使用している独自のソリューションを追加すると思いました。

文字列が数値であるかどうかを確認するもう1つの方法は、前述のstd::stod関数ですが、使用方法は少し異なります。私の使用例では、try-catchブロックを使用して、コードのように入力が文字列か数値かを確認します。

...
try {
    double n = stod(answer3);
    //This will only be reached if the number was converted properly.
    cout << "Correct" << endl;
} catch (invalid_argument &ex) {
    cout << "Enter Numbers Only" << endl;
}
...

このソリューションの主な問題は、数字で始まる(すべての数字ではない)文字列willが数字に変換されることです。これは、返された数値にstd::to_stringを使用して元の文字列と比較することで簡単に修正できます。

0
MarkSill

興味のある現象はisdigitであり、charunsigned charにキャストする必要があります。 ( ここ も参照してください)。

0
user3277268