यह निर्धारित करने के लिए कि यदि स्ट्रिंग C ++ वाली संख्या है?


136

मुझे एक फ़ंक्शन लिखने की कोशिश करने में काफी परेशानी हुई है जो जांचता है कि क्या एक स्ट्रिंग एक संख्या है। एक खेल के लिए मैं लिख रहा हूँ मुझे यह जाँचने की आवश्यकता है कि जो फ़ाइल मैं पढ़ रहा हूँ उससे एक पंक्ति एक संख्या है या नहीं (मुझे पता चल जाएगा कि क्या यह इस तरह से एक पैरामीटर है)। मैंने नीचे दिए गए फ़ंक्शन को लिखा है जो मुझे लगता है कि सुचारू रूप से काम कर रहा था (या मैंने गलती से इसे रोकने के लिए संपादित किया था या मैं स्किज़ोफ्रेनिक या विंडोज स्किज़ोफ्रेनिक हूं):

bool isParam (string line)
{
    if (isdigit(atoi(line.c_str())))
        return true;

    return false;
}

184
मुझे देखकर नफरत होती हैif (expr) return true; return false; ! बस लिखो return expr;
6

17
@ephemient मेरी शैली आपके जैसी ही है। लेकिन क्या यह वास्तव में एक बड़ी बात है?
ब्रेनन विंसेंट

2
आपका फ़ंक्शन प्रोटोटाइप उचित नहीं लगता है। क्यों bool isParam (स्थिरांक स्ट्रिंग और लाइन) का उपयोग नहीं
MikimotoH

4
हाँ। मुझे एक नई भाषा सीखने के दौरान लंबी शैली को कोडित करने की बुरी आदत है। मैं C ++ में नया हूं और "शॉर्टकट" (या कथित शॉर्टकट) से अधिक संकोच कर रहा हूं।
ब्रेंडन वेनस्टेन

57
@ ब्रेनन विंसेंट: हां, यह बहुत बड़ी बात है। यह गलतियों के रूप में की एक ही कक्षा में है if (expr) return expr; else return expr;, if (expr == true), (if expr != false), या if ((expr == true) == true)। वे सभी जटिलता का परिचय देते हैं जो कोड के लेखक, पाठक या संकलक को लाभ नहीं पहुंचाता है। अनावश्यक जटिलता का उन्मूलन कोई शॉर्टकट नहीं है; यह बेहतर सॉफ्टवेयर लिखने के लिए महत्वपूर्ण है।
MSalters

जवाबों:


148

जब तक आप एक गैर-अंक वर्ण नहीं ढूंढते तब तक सबसे प्रभावी तरीका स्ट्रिंग पर पुनरावृति करना होगा। यदि कोई गैर-अंक वर्ण हैं, तो आप स्ट्रिंग को संख्या नहीं मान सकते हैं।

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();
}

या यदि आप इसे C ++ 11 तरीके से करना चाहते हैं:

bool is_number(const std::string& s)
{
    return !s.empty() && std::find_if(s.begin(), 
        s.end(), [](unsigned char c) { return !std::isdigit(c); }) == s.end();
}

जैसा कि नीचे टिप्पणी में कहा गया है, यह केवल सकारात्मक पूर्णांक के लिए काम करता है। यदि आपको नकारात्मक पूर्णांक या अंशों का पता लगाने की आवश्यकता है, तो आपको अधिक मजबूत पुस्तकालय-आधारित समाधान के साथ जाना चाहिए। हालांकि, नकारात्मक पूर्णांक के लिए समर्थन जोड़ना बहुत तुच्छ है।


6
इसके अलावा नकारात्मक संख्या और गैर-पूर्ण संख्या को संभालना नहीं है। हम यह नहीं जान सकते हैं कि प्रश्न के आधार पर क्या आवश्यकताएँ हैं।
ब्रेनन विंसेंट

76
आप !s.empty() && s.find_first_not_of("0123456789") == std::string::npos;C ++ 03 वन-लाइनर के लिए भी उपयोग कर सकते हैं।
kbjorklu

8
इसके अलावा दशमलव संख्या को नहीं संभालता है जैसे: 1.23
littlecodefarmer758

3
@ दुश्मन लेबेऊ, हाँ यह करता है। यह वास्तव में स्ट्रिंग को एक में परिवर्तित नहीं कर रहा है int। यह सिर्फ यह पहचान रहा है कि क्या एक स्ट्रिंग संख्यात्मक अंकों से बना है। इससे कोई फर्क नहीं पड़ता कि स्ट्रिंग कितनी लंबी है।
चार्ल्स साल्विया

5
सी ++ 11 उदाहरण के काम को शामिल करने <string> <algorithm>और <cctype>बनाने के लिए मत भूलना ।
kR105

88

पहिया को क्यों मजबूत करें? C मानक लाइब्रेरी (C ++ में उपलब्ध है) में एक फ़ंक्शन है जो वास्तव में ऐसा करता है:

char* p;
long converted = strtol(s, &p, 10);
if (*p) {
    // conversion failed because the input wasn't a number
}
else {
    // use converted
}

यदि आप भिन्नों या वैज्ञानिक संकेतन को संभालना चाहते हैं, तो strtodइसके बजाय जाएँ (आपको doubleपरिणाम मिलेगा )।

यदि आप सी / सी ++ शैली ( "0xABC") में हेक्साडेसिमल और ऑक्टल स्थिरांक की अनुमति देना चाहते हैं , तो 0इसके बजाय अंतिम पैरामीटर बनाएं ।

आपका कार्य तब लिखा जा सकता है

bool isParam(string line)
{
    char* p;
    strtol(line.c_str(), &p, 10);
    return *p == 0;
}

4
यह फ़ंक्शन सामने की ओर सफेद स्थान को त्यागता है। इस प्रकार आपको isdigit के लिए पहले char की जाँच करनी होगी।
चमीक

1
@chmike: प्रश्न की मेरी समझ के आधार पर, प्रमुख व्हाट्सएप को छोड़ना सही व्यवहार है ( atoiजैसा कि प्रश्न में उपयोग किया गया है)।
बेन वोइगट

1
यह प्रश्न स्पष्ट रूप से निर्दिष्ट नहीं किया गया था, लेकिन आवश्यकता की मेरी समझ "जाँचता है कि क्या एक स्ट्रिंग एक संख्या है" का अर्थ है कि पूरी स्ट्रिंग संख्या है, इस प्रकार कोई रिक्त स्थान नहीं है। मुझे यह इंगित करने की आवश्यकता महसूस हुई कि इस संबंध में आपका उत्तर दूसरों से अलग है। यदि स्ट्रिंग के लिए संख्या के सामने स्थान होना ठीक है तो आपका उत्तर ठीक हो सकता है।
चमीक

1
@BenVoigt आप कह रहे हैं कि अगर यह बहुत ही सही है, तो pसेट हो जाएगा ? यही मैं नहीं देख रहा हूँ :(nullptrstrtol
जोनाथन एमई

2
@JonathanMee: नहीं, pस्ट्रिंग को समाप्त करने वाले NUL को इंगित किया जाएगा। तो p != 0और *p == 0
बेन वोइगट

33

C ++ 11 संकलक के साथ, गैर-नकारात्मक पूर्णांकों के लिए मैं कुछ इस तरह का उपयोग करूंगा ( ::इसके बजाय ध्यान दें std::):

bool is_number(const std::string &s) {
  return !s.empty() && std::all_of(s.begin(), s.end(), ::isdigit);
}

http://ideone.com/OjVJWh


1
यह सबसे अच्छा जवाब है।
मार्टिन ब्रॉडहर्स्ट

यदि स्ट्रिंग में utf8 अक्षर हैं, तो आपको रन टाइम एरर मिलेगा।
सिंह राजा

29

आप इसे बढ़ावा देने के साथ C ++ तरीका कर सकते हैं :: lexical_cast। यदि आप वास्तव में बढ़ावा देने का उपयोग नहीं करने पर जोर देते हैं तो आप बस यह जांच सकते हैं कि यह क्या करता है और क्या करता है। यह बहुत आसान है।

try 
{
  double x = boost::lexical_cast<double>(str); // double could be anything with >> operator.
}
catch(...) { oops, not a number }

21
try{} catch{}एक अच्छे विचार का उपयोग ? क्या हमें इससे जितना हो सके परहेज नहीं करना चाहिए?
नवाज

32
-1 गाली देने की कोशिश को पकड़ने के लिए ... blogs.msdn.com/b/ericlippert/archive/2008/09/10/…
NoSenseEtAl

14
यहाँ {} कैच {} का प्रयास उचित है। हालांकि, कैच (...) सिर्फ बुरा अभ्यास है। इस स्थिति में, अपने अपवाद हैंडलर के लिए बढ़ावा :: bad_lexical_cast का उपयोग करें।
नुस्कूलर

5
मुझे ऐसा लगता है कि यह एक फाइल से पढ़ने की कोशिश कर रहा है। कोई फर्क नहीं पड़ता कि आप फ़ाइल पर कितना जाँच करते हैं, आपको पता नहीं होगा कि क्या आप इसे तब तक पढ़ना संभव है जब तक आप इसे नहीं करते। यह या तो काम करने जा रहा है या नहीं। किस मामले में आपको एक अपवाद को पकड़ने की आवश्यकता है। तो इस मामले में मुझे लगता है कि यह करने का यह पूरी तरह से ठीक तरीका है।
केसी

4
@EarlGray - मुझे निश्चित रूप से यह सुनने में दिलचस्पी होगी कि ओएस पर निर्भर क्रियाएं विंडोज़ क्या लेंगी। मानक इस बारे में काफी स्पष्ट है कि इस कोड को कैसे व्यवहार करना चाहिए।
एडवर्ड स्ट्रेंज

16

मैं सिर्फ इस विचार को फेंकना चाहता था जो पुनरावृत्ति का उपयोग करता है लेकिन कुछ अन्य कोड उस पुनरावृत्ति को करते हैं:

#include <string.h>

bool is_number(const std::string& s)
{
    return( strspn( s.c_str(), "-.0123456789" ) == s.size() );
}

यह उस तरह से मजबूत नहीं है जैसा कि दशमलव बिंदु या माइनस साइन की जाँच करते समय होना चाहिए क्योंकि यह प्रत्येक के किसी भी स्थान और किसी भी स्थान पर होने की अनुमति देता है। अच्छी बात यह है कि यह कोड की एक एकल पंक्ति है और इसके लिए तीसरे पक्ष के पुस्तकालय की आवश्यकता नहीं है।

बाहर निकालें '।' और '-' यदि पॉजिटिव पूर्णांकों की अनुमति है।


त्रुटि: 'strspn' को इस दायरे में घोषित नहीं किया गया था, मुझे लगता है कि यह इसलिए है क्योंकि मुझे "#include" याद आ रही है, लेकिन एक क्या है
Qwertie

4
यदि आप उपयोग करने जा रहे हैं std::string, तो इसके find_first_not_ofसदस्य फ़ंक्शन का उपयोग करें ।
बेन वोइग्ट

5
यह विफल हो जाएगा यदि आप "12.3-4.55-" के तार में पास हो जाते हैं, जो स्पष्ट रूप से एक वैध संख्या नहीं है
Buzzrick

Buzzrick, प्रस्तावित उत्तर पहले से ही बताता है कि यह आपके द्वारा उल्लिखित गैर-संख्या के साथ विफल हो जाएगा।
डेविड रेक्टर

यदि आप इसे केवल "0123456789" तक सीमित करते हैं, तो सूत्र अहस्ताक्षरित पूर्णांक के लिए परीक्षण करने के लिए एकदम सही है
कोई भी विशेष

16

मैं एक regex दृष्टिकोण सुझाता हूँ। एक पूर्ण रेगेक्स-मैच (उदाहरण के लिए, बढ़ावा :: रेगेक्स का उपयोग करके )

-?[0-9]+([\.][0-9]+)?

दिखाएगा कि स्ट्रिंग एक संख्या है या नहीं। इसमें सकारात्मक और नकारात्मक संख्याएं, पूर्णांक के साथ-साथ दशमलव शामिल हैं।

अन्य विविधताएं:

[0-9]+([\.][0-9]+)?

(केवल सकारात्मक)

-?[0-9]+

(केवल पूर्णांक)

[0-9]+

(केवल सकारात्मक पूर्णांक)


अहम, मैंने std::regexgcc 4.7, gcc 4.8 के साथ उपयोग करने की कोशिश की - वे दोनों regexp के std::regex_errorकिसी भी संकेत पर फेंक देते हैं [, यहां तक ​​कि एक निर्दोष "[abc]" के लिए (क्या मैं ऐसा गलत करता हूं?)। clang-3.4 का अता-पता नहीं है <regex>। वैसे भी, यह सबसे अच्छा जवाब है, +1।
Dmytro Sirenko

3
@ एर्लग्रे: रेगेक्स केवल जीसीसी 4.9 से ठीक से उपलब्ध है
को कक्षा

13

यहां <regex>लाइब्रेरी का उपयोग करने का एक और तरीका है :

bool is_integer(const std::string & s){
    return std::regex_match(s, std::regex("[(-|+)|][0-9]+"));
}

आह, तो यह होगा। मैंने बेहतर समाधान के साथ अपडेट किया है। धन्यवाद।
mpataki14

ऐसा नहीं होना चाहिए "[(- (| + +) |] [0-9] +" (स्टार के बजाय), अन्यथा आपका रेगेक्स वैध संख्या के रूप में "-" या "+" पर मेल कर सकता है।
डेविड मुल्डर

अच्छा लगा। मुझे यकीन नहीं है कि उस प्रथम चरित्र वर्ग में क्या (ए, | और) कर रहे हैं - उन मेटाचैकर्स ने एक चरित्र वर्ग के अंदर अपना विशेष अर्थ खो दिया है जहां तक ​​मैं जानता हूं। कैसे के बारे में "^ [- +]? [0-9] + $"?
U007D

यह अक्षम हो सकता है। हर बार जब इसे बुलाया जाता है, तो इसे std :: regex constructor कहा जाता है जो regex को संकलित करता है।
user31264

12

इस समाधान से आप नकारात्मक से सकारात्मक संख्या और यहां तक ​​कि फ्लोट संख्या तक सब कुछ जांच सकते हैं। जब आप numपूर्णांक के प्रकार को बदलते हैं तो स्ट्रिंग में एक बिंदु होने पर आपको एक त्रुटि मिलेगी।

#include<iostream>
#include<sstream>
using namespace std;


int main()
{
      string s;

      cin >> s;

      stringstream ss;
      ss << s;

      float num = 0;

      ss >> num;

      if(ss.good()) {
          cerr << "No Valid Number" << endl;
      }
      else if(num == 0 && s[0] != '0') {
          cerr << "No Valid Number" << endl;
      }
      else {
          cout << num<< endl;
      }             
}

साबित: सी ++ प्रोग्राम


10

मैंने निम्नलिखित कोड को सबसे अधिक मजबूत पाया है (c ++ 11)। यह पूर्णांक और फ्लोट दोनों को पकड़ता है।

#include <regex>
bool isNumber( std::string token )
{
    return std::regex_match( token, std::regex( ( "((\\+|-)?[[:digit:]]+)(\\.(([[:digit:]]+)?))?" ) ) );
}

ऐसा लगता है कि लाइन using namespace std;अनावश्यक है।
XAM

5

धनात्मक पूर्णांक की जाँच के लिए यहां एक समाधान दिया गया है:

bool isPositiveInteger(const std::string& s)
{
    return !s.empty() && 
           (std::count_if(s.begin(), s.end(), std::isdigit) == s.size());
}

5

इसे इस्तेमाल करे:

isNumber(const std::string &str) {    
  return !str.empty() && str.find_first_not_of("0123456789") == string::npos;
}

1
केवल अहस्ताक्षरित पूर्णांक के लिए यह परीक्षण
कोई विशेष

4

ब्रेंडन इस

bool isNumber(string line) 
{
    return (atoi(line.c_str())); 
}

लगभग ठीक है।

किसी भी स्ट्रिंग को 0 से शुरू करना एक संख्या है, बस इस मामले के लिए एक चेक जोड़ें

bool isNumber(const string &line) 
{
 if (line[0] == '0') return true;
 return (atoi(line.c_str()));
}

टोनी डी। नोट की तरह "123hello" सच हो जाएगा।



3

C ++ 11 रेगेक्स ( #include <regex>) का उपयोग करके मेरा समाधान , इसका उपयोग अधिक सटीक जांच, जैसे unsigned int, doubleआदि के लिए किया जा सकता है :

static const std::regex INT_TYPE("[+-]?[0-9]+");
static const std::regex UNSIGNED_INT_TYPE("[+]?[0-9]+");
static const std::regex DOUBLE_TYPE("[+-]?[0-9]+[.]?[0-9]+");
static const std::regex UNSIGNED_DOUBLE_TYPE("[+]?[0-9]+[.]?[0-9]+");

bool isIntegerType(const std::string& str_)
{
  return std::regex_match(str_, INT_TYPE);
}

bool isUnsignedIntegerType(const std::string& str_)
{
  return std::regex_match(str_, UNSIGNED_INT_TYPE);
}

bool isDoubleType(const std::string& str_)
{
  return std::regex_match(str_, DOUBLE_TYPE);
}

bool isUnsignedDoubleType(const std::string& str_)
{
  return std::regex_match(str_, UNSIGNED_DOUBLE_TYPE);
}

आप इस कोड को http://ideone.com/lyDtfi पर पा सकते हैं , आवश्यकताओं को पूरा करने के लिए इसे आसानी से संशोधित किया जा सकता है।


मैं डाउनवोटर्स से अनुरोध करूंगा कि वे इस मुद्दे को समझने में मेरी मदद करें, मैं अपने उत्तर में सुधार करूंगा। धन्यवाद।
aniliitb10

2

Kbjorklu द्वारा एक टिप्पणी पर आधारित एक समाधान है:

bool isNumber(const std::string& s)
{
   return !s.empty() && s.find_first_not_of("-.0123456789") == std::string::npos;
}

साथ के रूप में डेविड रेक्टर जवाब यह कई डॉट्स या ऋण संकेत के साथ तार करने के लिए मजबूत नहीं है, लेकिन तुम सिर्फ पूर्णांकों के लिए जाँच करने के लिए उन अक्षरों को निकाल सकते हैं।


हालाँकि, मैं एक समाधान के लिए आंशिक हूं, जो बेन वोइगट के समाधान पर आधारित है , strtodदशमलव मान, वैज्ञानिक / इंजीनियरिंग अंकन, हेक्सिडेसिमल नोटेशन (C ++ 11), या यहां तक ​​कि INF / INFINITY / NAN (C ++ 11) को देखने के लिए cstdlib में उपयोग किया जाता है। है:

bool isNumberC(const std::string& s)
{
    char* p;
    strtod(s.c_str(), &p);
    return *p == 0;
}


2

का उपयोग कर <regex>। इस कोड का परीक्षण किया गया था!

bool isNumber(const std::string &token)
{
    return std::regex_match(token, std::regex("(\\+|-)?[0-9]*(\\.?([0-9]+))$"));
}

1

दस्तावेज़ीकरण को थोड़ा और अधिक परामर्श करने के बाद, मैं एक उत्तर के साथ आया जो मेरी आवश्यकताओं का समर्थन करता है, लेकिन शायद दूसरों के लिए उतना उपयोगी नहीं होगा। यहाँ यह (कष्टप्रद वापसी के बिना सच है और झूठे बयानों को वापस करना :-))

bool isNumber(string line) 
{
    return (atoi(line.c_str())); 
}

4
यदि संख्या होती है 0, तो आपको एक गलत-नकारात्मक मिलेगा।
चार्ल्स साल्विया

3
यह किसी भी अग्रणी संख्या को लौटाएगा, और आपको कचरा उठाने की चेतावनी नहीं देगा (उदाहरण के लिए "123hello" ==> 123)। @Charles: ब्रेंडन का उल्लेख है कि उन्हें केवल एक उत्तर पर एक टिप्पणी में सकारात्मक स्याही को पहचानने की आवश्यकता है।
टोनी डेलरो

1

मुझे लगता है कि इस नियमित अभिव्यक्ति को लगभग सभी मामलों को संभालना चाहिए

"^(\\-|\\+)?[0-9]*(\\.[0-9]+)?"

तो आप निम्न कार्य को आजमा सकते हैं जो दोनों (यूनिकोड और एएनएसआई) के साथ काम कर सकते हैं

bool IsNumber(CString Cs){
Cs.Trim();

#ifdef _UNICODE
std::wstring sr = (LPCWSTR)Cs.GetBuffer(Cs.GetLength());
return std::regex_match(sr, std::wregex(_T("^(\\-|\\+)?[0-9]*(\\.[0-9]+)?")));

#else
    std::string s = (LPCSTR)Cs.GetBuffer();
return std::regex_match(s, std::regex("^(\\-|\\+)?[0-9]*(\\.[0-9]+)?"));
#endif
}

1
include <string>

दोहरीकरण मान्य करने के लिए:

bool validateDouble(const std::string & input) {
int decimals = std::count(input.begin(), input.end(), '.'); // The number of decimals in the string
int negativeSigns = std::count(input.begin(), input.end(), '-'); // The number of negative signs in the string

if (input.size() == decimals + negativeSigns) // Consists of only decimals and negatives or is empty
    return false;
else if (1 < decimals || 1 < negativeSigns) // More than 1 decimal or negative sign
    return false;
else if (1 == negativeSigns && input[0] != '-') // The negative sign (if there is one) is not the first character
    return false;
else if (strspn(input.c_str(), "-.0123456789") != input.size()) // The string contains a character that isn't in "-.0123456789"
    return false;
return true;

}

Ints (नकारात्मक के साथ) मान्य करने के लिए

bool validateInt(const std::string & input) {
int negativeSigns = std::count(input.begin(), input.end(), '-'); // The number of negative signs in the string

if (input.size() == negativeSigns) // Consists of only negatives or is empty
    return false;
else if (1 < negativeSigns) // More than 1 negative sign
    return false;
else if (1 == negativeSigns && input[0] != '-') // The negative sign (if there is one) is not the first character
    return false;
else if (strspn(input.c_str(), "-0123456789") != input.size()) // The string contains a character that isn't in "-0123456789"
    return false;
return true;

}

Unsigned Ints वैलिडेट करने के लिए

bool validateUnsignedInt(const std::string & input) {
return (input.size() != 0 && strspn(input.c_str(), "0123456789") == input.size()); // The string is not empty and contains characters only in "0123456789"

}


1
bool isNumeric(string s){
    if ( !s.empty() && s[0] != '-' )
        s = "0" + s; //prepend 0

    string garbage;

    stringstream ss(s); 
    ss >> *(auto_ptr<double>(new double)) >> garbage;
/*
//the line above extracts the number into an anonymous variable. it could also be done like this:
double x;
ss >> x >> garbage;
*/
    //if there is no garbage return true or else return false
    return garbage.empty(); 
}

यह कैसे काम करता है: स्ट्रिंगस्ट्रीम >> अधिभार तार को विभिन्न अंकगणितीय प्रकारों में परिवर्तित कर सकता है जो कि वर्णों को क्रम से इस प्रकार से पढ़ता है (इस मामले में ss) जब तक यह पात्रों से बाहर नहीं निकलता है या अगला वर्ण संग्रहीत होने के मापदंड को पूरा नहीं करता है। गंतव्य चर प्रकार में।

उदाहरण 1:

stringstream ss("11");
double my_number;
ss >> my_number; //my number = 11

example2:

stringstream ss("011");
double my_number;
ss >> my_number; //my number = 11

Example3:

stringstream ss("11ABCD");
double my_number;
ss >> my_number; //my number = 11 (even though there are letters after the 11)

"कचरा" चर व्याख्या ":

क्यों नहीं जाँच करें कि क्या मेरे दोहरे में निष्कर्षण का एक वैध मूल्य है और क्या यह सच है अगर यह करता है?

उपर्युक्त उदाहरण 3 अभी भी सफलतापूर्वक 11 नंबर को my_number वैरिएबल में पढ़ेगा भले ही इनपुट स्ट्रिंग "11ABCD" (जो संख्या नहीं है)।

इस मामले को संभालने के लिए हम एक स्ट्रिंग वेरिएबल (जिसे मैंने कचरा कहा जाता है) में एक और निष्कर्षण कर सकते हैं जो कुछ भी पढ़ सकते हैं जो स्ट्रिंग बफर में टाइप डबल के चर में प्रारंभिक निष्कर्षण के बाद छोड़ दिया गया हो सकता है। यदि कुछ भी छोड़ दिया जाता है, तो इसे "कचरा" में पढ़ा जाएगा, जिसका अर्थ है कि पास किया गया पूर्ण स्ट्रिंग एक संख्या नहीं थी (यह सिर्फ एक के साथ शुरू होता है)। इस मामले में हम झूठे लौटना चाहते हैं;

पूर्वनिर्मित "0" स्पष्टीकरण ":

किसी एकल वर्ण को एक डबल में निकालने का प्रयास विफल हो जाएगा (0 को हमारे डबल में लौटना) लेकिन फिर भी चरित्र के बाद स्ट्रिंग बफर स्थिति को स्थानांतरित करेगा। इस स्थिति में हमारा पढ़ा हुआ कचरा खाली हो जाएगा, जिससे फ़ंक्शन गलत तरीके से सही लौटेगा। इसके आस-पास जाने के लिए मैंने एक 0 को स्ट्रिंग के लिए तैयार किया ताकि यदि उदाहरण में स्ट्रिंग पास हो जाए तो "a" यह "0a" में परिवर्तित हो जाता है जिससे 0 को डबल में निकाला जाएगा और "a" कचरे में निकाला जाएगा।

0 को प्रीपेडिंग करने से संख्या का मान प्रभावित नहीं होगा इसलिए नंबर अभी भी हमारे दोहरे चर में सही तरीके से निकाला जाएगा।


1
हालांकि यह कोड इस प्रश्न का उत्तर दे सकता है, कि यह कोड क्यों और / या इस बारे में अतिरिक्त संदर्भ प्रदान करता है कि यह प्रश्न इसके दीर्घकालिक मूल्य में सुधार करता है।
अजीन

1

यह जांचने के लिए कि क्या एक स्ट्रिंग एक पूर्णांक या फ्लोटिंग पॉइंट है या इसलिए आप इसका उपयोग कर सकते हैं:

 #include <sstream>

    bool isNumber(string str) {
    double d;
    istringstream is(str);
    is >> d;
    return !is.fail() && is.eof();
}

1
यह एक स्ट्रिंग के लिए 10 लौटेगा जिसमें "10_is_not_a_number" मान होगा।
कोरेडीडी

1

फिर भी एक और जवाब, जो उपयोग करता है stold(हालांकि आप भी उपयोग कर सकते हैं stof/ stodयदि आपको सटीक की आवश्यकता नहीं है)।

bool isNumeric(const std::string& string)
{
    std::size_t pos;
    long double value = 0.0;

    try
    {
        value = std::stold(string, &pos);
    }
    catch(std::invalid_argument&)
    {
        return false;
    }
    catch(std::out_of_range&)
    {
        return false;
    }

    return pos == string.size() && !std::isnan(value);
}


1

इसे इस्तेमाल करे:

bool checkDigit(string str)
{  
   int n=str.length();

   for(int i=0;    i   < n ;   i++)
   {
     if(str[i]<'0' || str[i]>'9')
       return false;
   }

   return true;
}

1

यदि आप एक स्ट्रिंग को बढ़ावा देने के लिए पूर्णांक के लिए परिवर्तनीय है :: lexical_cast का उपयोग करके परीक्षण कर सकते हैं । यदि यह bad_lexical_cast अपवाद फेंकता है तो स्ट्रिंग परिवर्तित नहीं किया जा सकता है, अन्यथा यह कर सकता है।

नीचे ऐसे परीक्षण कार्यक्रम का उदाहरण देखें:

#include <boost/lexical_cast.hpp>
#include <iostream>

int main(int, char** argv)
{
        try
        {
                int x = boost::lexical_cast<int>(argv[1]);
                std::cout << x << " YES\n";
        }
        catch (boost::bad_lexical_cast const &)
        {
                std:: cout << "NO\n";
        }
        return 0;
}

नमूना निष्पादन:

# ./a.out 12
12 YES
# ./a.out 12/3
NO

0

कुछ महीने पहले, मैंने यह निर्धारित करने के लिए एक तरीका लागू किया कि क्या कोई स्ट्रिंग पूर्णांक, हेक्साडेसिमल या डबल है।

enum{
        STRING_IS_INVALID_NUMBER=0,
        STRING_IS_HEXA,
        STRING_IS_INT,
        STRING_IS_DOUBLE
};

bool isDigit(char c){
    return (('0' <= c) && (c<='9'));
}

bool isHexaDigit(char c){
    return ((('0' <= c) && (c<='9')) || ((tolower(c)<='a')&&(tolower(c)<='f')));
}


char *ADVANCE_DIGITS(char *aux_p){

    while(CString::isDigit(*aux_p)) aux_p++;
    return aux_p;
}

char *ADVANCE_HEXADIGITS(char *aux_p){

    while(CString::isHexaDigit(*aux_p)) aux_p++;
    return aux_p;
}


int isNumber(const string & test_str_number){
    bool isHexa=false;
    char *str = (char *)test_str_number.c_str();

    switch(*str){
    case '-': str++; // is negative number ...
               break;
    case '0': 
              if(tolower(*str+1)=='x')  {
                  isHexa = true;
                  str+=2;
              }
              break;
    default:
            break;
    };

    char *start_str = str; // saves start position...
    if(isHexa) { // candidate to hexa ...
        str = ADVANCE_HEXADIGITS(str);
        if(str == start_str)
            return STRING_IS_INVALID_NUMBER;

        if(*str == ' ' || *str == 0) 
            return STRING_IS_HEXA;

    }else{ // test if integer or float
        str = ADVANCE_DIGITS(str);
        if(*str=='.') { // is candidate to double
            str++;
            str = ADVANCE_DIGITS(str);
            if(*str == ' ' || *str == 0)
                return STRING_IS_DOUBLE;

            return STRING_IS_INVALID_NUMBER;
        }

        if(*str == ' ' || *str == 0)
            return STRING_IS_INT;

    }

    return STRING_IS_INVALID_NUMBER;


}

फिर अपने कार्यक्रम में आप आसानी से फ़ंक्शन को संख्या में बदल सकते हैं यदि आप निम्न कार्य करते हैं,

string val; // the string to check if number...

switch(isNumber(val)){
   case STRING_IS_HEXA: 
   // use strtol(val.c_str(), NULL, 16); to convert it into conventional hexadecimal
   break;
   case STRING_IS_INT: 
   // use (int)strtol(val.c_str(), NULL, 10); to convert it into conventional integer
   break;
   case STRING_IS_DOUBLE:
   // use atof(val.c_str()); to convert it into conventional float/double
   break;
}

आप महसूस कर सकते हैं कि फ़ंक्शन 0 का पता लगाएगा यदि संख्या का पता नहीं लगा था। 0 इसे गलत (बूलियन की तरह) माना जा सकता है।


0

मैं एक साधारण सम्मेलन प्रस्तावित करता हूं:

यदि ASCII में रूपांतरण> 0 है या यह 0 से शुरू होता है तो यह एक संख्या है। यह सही नहीं है, लेकिन तेज है।

कुछ इस तरह:

string token0;

if (atoi(token0.c_str())>0 || isdigit(token0.c_str()[0]) ) { //this is a value
    // do what you need to do...
}

0

यह फ़ंक्शन सभी संभावित मामलों की देखभाल करता है:

bool AppUtilities::checkStringIsNumber(std::string s){
    //Eliminate obvious irritants that could spoil the party
    //Handle special cases here, e.g. return true for "+", "-", "" if they are acceptable as numbers to you
    if (s == "" || s == "." || s == "+" || s == "-" || s == "+." || s == "-.") return false;

    //Remove leading / trailing spaces **IF** they are acceptable to you
    while (s.size() > 0 && s[0] == ' ') s = s.substr(1, s.size() - 1);
    while (s.size() > 0 && s[s.size() - 1] == ' ') s = s.substr(0, s.size() - 1);


    //Remove any leading + or - sign
    if (s[0] == '+' || s[0] == '-')
        s = s.substr(1, s.size() - 1);

    //Remove decimal points
    long prevLength = s.size();

    size_t start_pos = 0;
    while((start_pos = s.find(".", start_pos)) != std::string::npos) 
        s.replace(start_pos, 1, "");

    //If the string had more than 2 decimal points, return false.
    if (prevLength > s.size() + 1) return false;

    //Check that you are left with numbers only!!
    //Courtesy selected answer by Charles Salvia above
    std::string::const_iterator it = s.begin();
    while (it != s.end() && std::isdigit(*it)) ++it;
    return !s.empty() && it == s.end();

    //Tada....
}

0

क्या आप यह निर्धारित करने के लिए बस sscanf के रिटर्न कोड का उपयोग कर सकते हैं?

bool is_number(const std::string& s)
{
    int value;
    int result = sscanf(valueStr.c_str(), "%d", &value);
    return (result != EOF && readResult != 0);
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.