স্ট্রিং সি ++ সহ একটি সংখ্যা কিনা তা কীভাবে নির্ধারণ করবেন?


136

একটি ফাংশন লিখতে চেষ্টা করতে আমার বেশ খানিকটা সমস্যা হয়েছে যা স্ট্রিংয়ের সংখ্যা কিনা তা পরীক্ষা করে। একটি গেমের জন্য আমি লিখছি আমার কেবল যাচাই করা দরকার যে ফাইলটি আমি পড়ছি তার একটি লাইন একটি নম্বর কিনা না (আমি জানতে পারি এটি এইভাবে প্যারামিটার কিনা)। আমি নীচের ফাংশনটি লিখেছিলাম যা আমি বিশ্বাস করি যে সুচারুভাবে কাজ করছে (বা আমি ঘটনাক্রমে এটি বন্ধ করার জন্য সম্পাদনা করেছি বা আমি সিজোফ্রেনিক বা উইন্ডোজ সিজোফ্রেনিক):

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

    return false;
}

184
আমি দেখে ঘৃণা করি if (expr) return true; return false;! শুধু লিখুন return expr;
প্রাক্তন

17
@ প্রিমিয়েন্ট আমার স্টাইলটি আপনার মতোই করা। তবে আসলেই কি এটি বড় ব্যাপার?
ব্রেনান ভিনসেন্ট

2
আপনার ফাংশন প্রোটোটাইপ উপযুক্ত মনে হয় না। বুল ইসপাম (কনস্ট্রিং স্ট্রিং এন্ড লাইন) কেন ব্যবহার করবেন না
মিকিমোটো

4
হ্যাঁ। একটি নতুন ভাষা শেখার সময় আমার দীর্ঘ-শৈলীর কোডিংয়ের অভ্যাস রয়েছে। আমি সি ++ তে নতুন এবং "শর্টকাট" (বা অনুভূত শর্টকাটগুলি) সম্পর্কে আরও দ্বিধাগ্রস্ত।
ব্রেন্ডন ওয়েইনস্টেইন

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

বা আপনি যদি এটি করতে চান সি ++ 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;সি ++ 03 ওয়ান-লাইনারের জন্যও ব্যবহার করতে পারেন ।
কেবিজোর্কলু

8
দশমিক সংখ্যাগুলিও হ্যান্ডেল করে না যেমন: 1.23
littlecodefarmer758

3
@ রেমি লেবু, হ্যাঁ তা করে। এটি আসলে স্ট্রিংটিকে একটি তে রূপান্তর করে না int। এটি কেবল সনাক্ত করছে যে কোনও স্ট্রিং সংখ্যাসূচক দ্বারা গঠিত whether স্ট্রিংটি কত দীর্ঘ তা বিবেচনা করে না।
চার্লস সালভিয়া

5
সি ++ 11 উদাহরণস্বরূপ কাজটি অন্তর্ভুক্ত করতে <string> <algorithm>এবং <cctype>তৈরি করতে ভুলবেন না ।
kR105

88

চাকা পুনরুদ্ধার কেন? সি স্ট্যান্ডার্ড লাইব্রেরিতে (সি ++ তেও উপলভ্য) এর একটি ফাংশন রয়েছে যা ঠিক এটি করে:

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
এই ফাংশনটি সামনে সাদা স্থানকে ছাড়ায়। আপনাকে এইভাবে ডিজিটের জন্য প্রথম চরটি পরীক্ষা করতে হবে।
chmike

1
@ চিমিক: প্রশ্ন সম্পর্কে আমার বোঝার উপর ভিত্তি করে, শীর্ষস্থানীয় সাদা অংশকে ত্যাগ করা সঠিক আচরণ ( atoiপ্রশ্নটিতে ব্যবহৃত এটিও এটি করে)।
বেন ভয়েগট

1
প্রশ্নটি স্পষ্টভাবে এটি নির্দিষ্ট করে নি, তবে "স্ট্রিং একটি নম্বর কিনা তা পরীক্ষা করে নেওয়ার" প্রয়োজনীয়তা সম্পর্কে আমার বোঝার অর্থ এই যে পুরো স্ট্রিংটি সংখ্যা, সুতরাং কোনও স্থান নেই। আমি উল্লেখ করার প্রয়োজন অনুভব করেছি যে আপনার উত্তর এই ক্ষেত্রে অন্যদের চেয়ে আলাদা। আপনার উত্তরটি ঠিক আছে যদি সংখ্যার সামনে স্ট্রিংয়ের জন্য স্ট্রিং ঠিক থাকে for
chmike

1
@ BenVoigt আপনি বলছেন যে এটি সফল pহবে nullptrযদি সেট করা হবে strtol, তাই না? এটি আমি যা দেখছি তা নয় :(
জোনাথন মে

2
@ জোনাথনমি: না, এনআুলের pদিকে ইঙ্গিত করবে যা স্ট্রিংটি বন্ধ করে দেয়। তাই p != 0এবং *p == 0
বেন ভয়েগট

33

সি ++ ১১ সংকলক সহ, অ-নেতিবাচক পূর্ণসংখ্যার জন্য আমি এই জাতীয় কিছু ব্যবহার করব (এর ::পরিবর্তে নোট করুন 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

আপনি এটি বুস্ট :: লেক্সিক্যাল_কাস্টের মাধ্যমে সি ++ উপায়ে করতে পারেন। আপনি যদি সত্যিই বুস্ট ব্যবহার না করার জন্য জেদ করেন তবে আপনি এটি পরীক্ষা করে দেখতে পারেন এবং এটি কী করে। এটা বেশ সহজ।

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
{} ক্যাচ} try চেষ্টা করুন এখানে উপযুক্ত। তবে, ধরা (...) কেবল খারাপ অভ্যাস। এই ক্ষেত্রে, আপনার ব্যতিক্রম হ্যান্ডলারটির জন্য বুস্ট :: খারাপ_ল্লিক্যাল_কাস্ট ব্যবহার করুন।
নিউস্কুলার

5
আমার মনে হচ্ছে এটি কোনও ফাইল থেকে পড়ার চেষ্টা করছে। আপনি ফাইলটিতে কতখানি চেক করছেন তা বিবেচনা করে না আপনি এটি না করা পর্যন্ত এটি থেকে পড়া সম্ভব কিনা তা আপনি জানতে পারবেন না। এটি হয় কাজ যাচ্ছে না। কোন ক্ষেত্রে আপনাকে একটি ব্যতিক্রম ধরা দরকার। সুতরাং এই ক্ষেত্রে আমি মনে করি এটি এটি করার একটি সম্পূর্ণ সূক্ষ্ম উপায়।
কেসি

4
@ ইরলগ্রী - ওএস নির্ভরশীল ক্রিয়াকলাপগুলি উইন্ডোজ কী গ্রহণ করবে তা আমি শুনতে আগ্রহী। এই কোডটি কীভাবে আচরণ করা উচিত সে সম্পর্কে মানকটি বেশ স্পষ্ট।
এডওয়ার্ড স্ট্রেঞ্জ

16

আমি কেবল এই ধারণাটি ফেলে দিতে চেয়েছিলাম যা পুনরাবৃত্তি ব্যবহার করে তবে অন্য কিছু কোড সেই পুনরাবৃত্তিটি করে:

#include <string.h>

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

দশমিক পয়েন্ট বা বিয়োগ চিহ্ন সন্ধান করার সময় এটি হওয়া উচিত এটির মতো দৃ rob় নয় কারণ এটি প্রতিটি জায়গায় এবং যে কোনও স্থানে একের অধিক হতে দেয়। ভাল জিনিসটি এটি কোডের একক লাইন এবং তৃতীয় পক্ষের লাইব্রেরির প্রয়োজন হয় না।

নাও '.' এবং '-' যদি ইতিবাচক পূর্ণসংখ্যাগুলি মঞ্জুরিপ্রাপ্ত হয়।


ত্রুটি: 'স্টারস্প্প' এই সুযোগে ঘোষিত হয়নি আমার মনে হয় এটি কারণ আমি একটি "# অন্তর্ভুক্ত" মিস করছি তবে একটি
কিওয়ার্টি

4
আপনি যদি ব্যবহার করতে যাচ্ছেন তবে std::stringএর find_first_not_ofসদস্য ফাংশনটি ব্যবহার করুন ।
বেন ভয়েগট

5
আপনি যদি "12.3-4.55-" এর স্ট্রিংটিতে পাস করেন তবে এটি ব্যর্থ হবে যা স্পষ্টতই কোনও বৈধ সংখ্যা নয়
বুজ্রিক 18

বুজ্রিক, প্রস্তাবিত উত্তর ইতিমধ্যে জানিয়েছে যে এটি আপনার উল্লিখিত নন-সংখ্যাটির সাথে ব্যর্থ হবে।
ডেভিড রেক্টর

যদি আপনি এটি কেবল "0123456789" এ সীমাবদ্ধ করেন তবে সূত্রটি স্বাক্ষরবিহীন পূর্ণসংখ্যার জন্য পরীক্ষা করার জন্য উপযুক্ত
কোনও

16

আমি একটি রেজেক্স পদ্ধতির পরামর্শ দেব সাথে একটি পূর্ণ রেগেক্স-ম্যাচ (উদাহরণস্বরূপ, বুস্ট :: রেজেক্স ব্যবহার করে )

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

স্ট্রিংটি একটি সংখ্যা কিনা তা প্রদর্শন করবে। এর মধ্যে ধনাত্মক এবং negativeণাত্মক সংখ্যা, পূর্ণসংখ্যার পাশাপাশি দশমিক।

অন্যান্য প্রকরণ:

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

(শুধুমাত্র ইতিবাচক)

-?[0-9]+

(শুধুমাত্র পূর্ণসংখ্যা)

[0-9]+

(শুধুমাত্র ইতিবাচক পূর্ণসংখ্যা)


আহেম, আমি std::regexজিসিসি ৪.7, জিসিসি ৪.৮ ব্যবহার করার চেষ্টা করেছি - তারা দুজনেই রেগএক্সএক্স- std::regex_errorতে কোনও চিহ্ন প্রয়োগ করে [, এমনকি একজন নির্দোষ "[এবিসি]" এর জন্যও (আমি কি এটি ভুল করি?)। ঝনঝন -৩.৪ মোটেই অবগত <regex>নয়। যাইহোক, এটি স্যানিট উত্তর বলে মনে হচ্ছে, +1।
Dmytro সিরেনকো

3
@ আর্থল্রে: রেগেক্স কেবলমাত্র জিসিসি ৪.৯ থেকে সঠিকভাবে উপলভ্য
অরবিট-এ

13

পাঠাগারটি ব্যবহার করে এটি করার আরও একটি উপায় এখানে রয়েছে <regex>:

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

আহ, তাই হবে। আমি একটি ভাল সমাধান সঙ্গে আপডেট করেছি। ধন্যবাদ।
এমপটাকি 14

এটি "[(- | +) |] হওয়া উচিত নয়" [0-9] + "(তারার পরিবর্তে প্লাস), অন্যথায় আপনার রেজেক্সটি একটি বৈধ সংখ্যা হিসাবে" - "বা" + "এর সাথে মিলতে পারে।
ডেভিড মুলদার

খুশী হলাম। আমি নিশ্চিত নই যে (, | এবং) প্রথম চরিত্রের শ্রেণিতে কী করছে - আমি যতটা অবগত রয়েছি met মেটাচার্যাক্টরা একটি চরিত্র শ্রেণীর ভিতরে তাদের বিশেষ অর্থ হারিয়ে ফেলে। "^ [- +] কীভাবে? [0-9] + $"?
U007D

এটি অদক্ষ হতে পারে। প্রতিবার যখন এটি বলা হয়, তখন এটি স্টেডি :: রেজেক্স কনস্ট্রাক্টরকে কল করে যা রেজেক্সকে সংকলন করে।
user31264

12

এই সমাধানের সাহায্যে আপনি negativeণাত্মক থেকে ধনাত্মক সংখ্যা এবং এমনকি ভাসমান সংখ্যা পর্যন্ত সবকিছু পরীক্ষা করতে পারেন। আপনি যখন 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

আমি নিম্নলিখিত কোডটি সবচেয়ে শক্তিশালী (সি ++ 11) পেয়েছি। এটি পূর্ণসংখ্যা এবং ভাসমান উভয়ই ধরে ফেলে।

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

মনে হচ্ছে লাইনটি using namespace std;অপ্রয়োজনীয়।
জ্যাম

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

ofc "123hello" সত্য ফিরে আসবে যেমন টনি ডি লিখেছেন।



3

সি ++ 11 Regex (ব্যবহার করে আমার সমাধান #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

কেবিজর্কলু একটি মন্তব্যের ভিত্তিতে একটি সমাধান :

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

সঙ্গে ডেভিড রেক্টর এর উত্তর একাধিক বিন্দু বা মাইনাস নিদর্শনাবলী নিয়ে স্ট্রিং শক্তসমর্থ নয়, কিন্তু আপনি শুধু পূর্ণসংখ্যার জন্য চেক করতে যারা অক্ষর অপসারণ করতে পারেন।


যাইহোক, আমি বেনstrtod ভয়েগ্টের সমাধানের ভিত্তিতে একটি সমাধানের আংশিক , দশমিক মান, বৈজ্ঞানিক / ইঞ্জিনিয়ারিং স্বরলিপি, হেক্সিডিসিমাল স্বরলিপি (সি ++ 11), এমনকি আইএনএফ / তথ্য / এনএএন (সি ++ 11) দেখতে সিএসডিডিলেব ব্যবহার করে হল:

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
এটি কোনও শীর্ষস্থানীয় নম্বর ফিরিয়ে দেবে এবং আপনাকে পিছনে আবর্জনা (যেমন "123 হেলো" ==> 123) সম্পর্কে সতর্ক করবে না। @ চার্লস: ব্রেন্ডন উল্লেখ করেছেন যে কেবলমাত্র একটি উত্তরের মন্তব্যে তিনি ইতিবাচক ইন্টগুলি চিনতে পারবেন recognize
টনি দেলরোয়

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 বৈধকরণের জন্য (gণাত্মক সহ)

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;

}

স্বাক্ষরযুক্ত ইনটগুলি বৈধকরণের জন্য

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

এটি কীভাবে কাজ করে: স্ট্রিং স্ট্রিম >> ওভারলোড স্ট্রিং স্ট্রিম থেকে ধারাবাহিকভাবে অক্ষরগুলি পড়ার মাধ্যমে স্ট্রিং স্ট্রিমের (এসএসএস) অক্ষরগুলি না পড়ে বা পরবর্তী অক্ষর সংরক্ষণের মানদণ্ড পূরণ না করে স্ট্রিংগুলিকে বিভিন্ন গাণিতিক ধরণের রূপান্তর করতে পারে over গন্তব্য পরিবর্তনশীল প্রকারের মধ্যে।

example1:

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 এখনও ইনপুট স্ট্রিং "11ABCD" (যা একটি সংখ্যা নয়) এমনকি 11 নম্বরটি my_number ভেরিয়েবলটিতে সফলভাবে পড়বে।

এই কেসটি হ্যান্ডেল করতে আমরা স্ট্রিং ভেরিয়েবলে (যা আমি আবর্জনা নামকরণ করেছি) আরেকটি নিষ্কাশন করতে পারি যা প্রারম্ভিক এক্সট্রাকশনটির পরে স্ট্রিং বাফারটিতে ডাবল টাইপের মধ্যে ফেলে রাখা হতে পারে এমন কিছু পড়তে পারে। যদি কিছু ছেড়ে যায় তবে এটি "আবর্জনা" পড়তে হবে যার অর্থ পাস করা স্ট্রিংটি কোনও সংখ্যা ছিল না (এটি কেবল একটি দিয়ে শুরু হয়)। এই ক্ষেত্রে আমরা মিথ্যা ফিরতে চাই;

চাপ দেওয়া "0" ব্যাখ্যা ":

একটি একক অক্ষরকে দ্বিগুণে আনার চেষ্টা ব্যর্থ হবে (0 আমাদের ডাবলে ফিরে আসবে) তবে স্ট্রিং বাফার অবস্থানটি অক্ষরের পরে স্থানান্তরিত করবে। এই ক্ষেত্রে আমাদের আবর্জনা খালি খালি হবে যা ফাংশনটি ভুলভাবে সত্যে ফিরে আসবে। এটিকে ঘুরে দেখার জন্য আমি স্ট্রিংটিতে 0 টি প্রম্পেন্ড করে রেখেছিলাম যাতে উদাহরণস্বরূপ যদি স্ট্রিংটি "a" হয় তবে এটি "0a" এ পরিবর্তিত হয় যাতে 0 টি ডাবলকে বের করা হবে এবং "একটি" আবর্জনায় সরানো হবে।

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" মান ধারণ করে।
KorreyD

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

আপনি পরীক্ষা করতে পারেন যদি স্ট্রিংটি বুস্ট :: লেক্সিক্যাল_কাস্ট ব্যবহার করে পূর্ণসংখ্যায় রূপান্তরিত হয় । যদি এটি খারাপ_লেক্সিকাল_কাস্ট ব্যতিক্রম ছুঁড়ে ফেলে তবে স্ট্রিং রূপান্তর করা যায়নি, অন্যথায় এটি পারে।

নীচে যেমন একটি পরীক্ষা প্রোগ্রামের উদাহরণ দেখুন:

#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

আপনি যদি কেবল কোনও এসসিএনএফের রিটার্ন কোডটি কোনও পূর্বনির্মাণের জন্য নির্ধারণ করতে ব্যবহার করতে পারেন?

bool is_number(const std::string& s)
{
    int value;
    int result = sscanf(valueStr.c_str(), "%d", &value);
    return (result != EOF && readResult != 0);
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.