अगर C ++ std :: string एक निश्चित स्ट्रिंग से शुरू होती है, और एक स्ट्रिंग को int में परिवर्तित करती है, तो मैं कैसे जांचूं?


242

C ++ में मैं निम्नलिखित (पायथन स्यूडोकोड) कैसे लागू कर सकता हूं?

if argv[1].startswith('--foo='):
    foo_value = int(argv[1][len('--foo='):])

(उदाहरण के लिए, यदि argv[1]है --foo=98, तो foo_valueहै 98।)

अद्यतन: मैं बूस्ट में देखने में संकोच कर रहा हूं, क्योंकि मैं सिर्फ एक साधारण छोटे कमांड-लाइन टूल में बहुत छोटा बदलाव कर रहा हूं (मुझे यह सीखना नहीं है कि एक मामूली के लिए बूस्ट कैसे लिंक करें और उपयोग करें परिवर्तन)।


यह भी दिलचस्प है।
manlio

जवाबों:


447

एक अधिभार का उपयोग करें rfindजिसमें posपैरामीटर है:

std::string s = "tititoto";
if (s.rfind("titi", 0) == 0) {
  // s starts with prefix
}

किसको और क्या चाहिए? शुद्ध एसटीएल!

कई लोगों ने इसका अर्थ "उपसर्ग की तलाश में पूरे स्ट्रिंग के माध्यम से पीछे की ओर खोज" किया है। यह गलत परिणाम देगा (उदाहरण के लिए string("tititito").rfind("titi")2 इसलिए जब तुलना == 0झूठी हो जाएगी) और यह अक्षम होगा (केवल शुरुआत के बजाय पूरे स्ट्रिंग के माध्यम से देखना)। लेकिन यह ऐसा नहीं करता है क्योंकि यह posपैरामीटर को पास करता है 0, जो खोज को केवल उस स्थिति या पहले के मैच से सीमित करता है । उदाहरण के लिए:

std::string test = "0123123";
size_t match1 = test.rfind("123");    // returns 4 (rightmost match)
size_t match2 = test.rfind("123", 2); // returns 1 (skipped over later match)
size_t match3 = test.rfind("123", 0); // returns std::string::npos (i.e. not found)

32
यह उत्तर सबसे अधिक मतदान होना चाहिए न कि एक को बढ़ावा देना: डी जब आप पहले से ही एसटीएल है तो दूसरे पुस्तकालय का उपयोग क्यों करें।
इलियु अतुदोसी

@ स्वीसरबर्बर ।देव, मैं आपके पहले विवाद पर उलझन में हूं। findयदि स्ट्रिंग titiकी शुरुआत में है तो से वापसी मूल्य केवल शून्य होगा । यदि यह कहीं और पाया जाता है, तो आपको एक गैर-शून्य रिटर्न मान मिलेगा और यदि यह नहीं मिला है, तो आपको वह मिलेगा nposजो गैर-शून्य है। यह मानकर कि मैं सही हूं, मैं इस उत्तर को पसंद करूंगा क्योंकि मुझे किसी भी गैर-मानक सामान को लाने की आवश्यकता नहीं है (हां, मुझे पता है कि बूस्ट हर जगह है, मैं बस इस तरह से साधारण सामान के लिए कोर सी ++ लिबास पसंद करूंगा)।
पैक्सिडाब्लो

@paxdiablo: आप सही हैं, यह वास्तव में जाँच करता है कि क्या यह शुरू होता है titi, लेकिन रूपांतरण भाग गायब है।
swisgerber.dev

2
क्या हमारे पास कोई सबूत है कि यह अधिकांश संकलक में अनुकूलित है? मुझे कहीं भी "खोज" या "रिफ़्ड्स" का उल्लेख नहीं मिला है, यह उस मूल्य के आधार पर अनुकूलन है जो इसके खिलाफ जाँच कर रहा है।
सुपरजियाई

2
@alcoforado "rfind स्ट्रिंग के पीछे से शुरू होगा ..." नहीं, यह केवल उस के अधिभार पर लागू होता है जो rfind()एक posपैरामीटर नहीं लेता है । यदि आप एक अधिभार का उपयोग करते हैं जो एक posपैरामीटर लेता है तो यह पूरे स्ट्रिंग की खोज नहीं करेगा, केवल उस स्थिति और पहले। (जैसे पैरामीटर के find()साथ नियमित रूप से posकेवल उसी स्थिति में या बाद में दिखता है।) इसलिए यदि आप पास करते हैं pos == 0, जैसा कि इस उत्तर में दिखाया गया है, तो यह शाब्दिक रूप से केवल उसी स्थिति में मैचों के लिए विचार करेगा। वह पहले से ही जवाब और टिप्पणी दोनों में समझा रहा था।
आर्थर टाका

188

आप इसे इस तरह से करेंगे:

std::string prefix("--foo=");
if (!arg.compare(0, prefix.size(), prefix))
    foo_value = atoi(arg.substr(prefix.size()).c_str());

ऐसे Boost.ProgramOptions के रूप में एक काम की तलाश में है कि यह आपके लिए भी एक अच्छा विचार है।


7
इसके साथ सबसे बड़ी समस्या यह है कि atoi("123xyz")रिटर्न 123, जबकि पायथन का int("123xyz")अपवाद है।
टॉम

वर्कअराउंड, हम कर सकते हैं, एक sscanf () के लिए है और परिणाम और मूल की तुलना करें, यह तय करने के लिए कि अपवाद को आगे बढ़ाएं या फेंक दें।
रूपेश मजेती

1
या बस के atoiसाथ बदलें strtolया strtoll, जो हमें इनपुट मूल्य में त्रुटि की स्थिति का पता लगाने देता है।
टॉम

1
यह बेहतर समाधान है rfindजो काम करने के लिए अनुकूलन पर निर्भर करता है।
कैलमेरियस

143

पूर्णता के लिए, मैं इसे करने का C तरीका बताऊंगा:

यदि strआपका मूल स्ट्रिंग है, substrतो वह सबस्ट्रिंग है जिसे आप जांचना चाहते हैं, फिर

strncmp(str, substr, strlen(substr))

के साथ शुरू होता है, 0तो वापस आ जाएगा । फ़ंक्शन और सी हेडर फ़ाइल में हैंstrsubstrstrncmpstrlen<string.h>

(मूल रूप से यहां यासीन रऊफ द्वारा पोस्ट किया गया , मार्कअप जोड़ा गया)

केस-असंवेदनशील तुलना के लिए, के strnicmpबजाय का उपयोग करें strncmp

यह ऐसा करने का C तरीका है, C ++ स्ट्रिंग्स के लिए आप इसी तरह के फ़ंक्शन का उपयोग कर सकते हैं:

strncmp(str.c_str(), substr.c_str(), substr.size())

9
वास्तव में, हर कोई बस "बूस्ट का उपयोग करें" और मैं एक के लिए एक stl या OS लाइब्रेरी संस्करण के लिए आभारी लगता है
फोर्स गैया

हाँ। हालाँकि, यह मानता है कि स्ट्रिंग में कोई अशक्त वर्ण नहीं है। यदि यह मामला नहीं है - एक का उपयोग करना चाहिएmemcmp()
Avishai Y

कोई भी इस सरल सुंदर समाधान के अलावा किसी और चीज का उपयोग क्यों करेगा?
एडम ज़हरान

88

यदि आप पहले से ही बूस्ट का उपयोग कर रहे हैं, तो आप इसे स्ट्रिंग एल्गोरिदम + बूस्ट लेक्सिकल कास्ट को बढ़ावा देने के साथ कर सकते हैं :

#include <boost/algorithm/string/predicate.hpp>
#include <boost/lexical_cast.hpp>

try {    
    if (boost::starts_with(argv[1], "--foo="))
        foo_value = boost::lexical_cast<int>(argv[1]+6);
} catch (boost::bad_lexical_cast) {
    // bad parameter
}

इस तरह का दृष्टिकोण, यहां दिए गए कई अन्य उत्तरों की तरह, बहुत ही सरल कार्यों के लिए ठीक है, लेकिन लंबे समय में आप आमतौर पर कमांड लाइन पार्सिंग लाइब्रेरी का उपयोग करके बेहतर होते हैं। बूस्ट में एक ( Boost.Program_options ) है, जो समझ में आ सकता है कि क्या आप पहले से ही बूस्ट का उपयोग कर रहे हैं।

अन्यथा "c ++ कमांड लाइन पार्सर" की खोज से कई विकल्प मिलेंगे।


107
एक स्ट्रिंग उपसर्ग की जांच के लिए भारी निर्भरता में खींचना कैनन के साथ पक्षियों की शूटिंग की तरह है।
तोबी

150
"बूस्ट का उपयोग करें" हमेशा गलत जवाब होता है जब कोई पूछता है कि सी ++ में एक साधारण स्ट्रिंग ऑपरेशन कैसे किया जाए।
ग्लेन मेनार्ड

90
बूस्ट सुझाने के लिए माइनस 1
बदसूरत

37
यहां बूस्ट का उपयोग करना सही है, यदि आप पहले से ही अपने प्रोजेक्ट में बूस्ट का उपयोग करते हैं।
एलेक्स चे

17
उत्तर "यदि आप बूस्ट का उपयोग कर रहे हैं ..." के साथ उपसर्ग किया गया है। स्पष्ट रूप से यह सही उत्तर है "... यदि आप बूस्ट का उपयोग कर रहे हैं"। यदि नहीं, तो @Thomas
NuSkooler

82

कोड मैं खुद का उपयोग करें:

std::string prefix = "-param=";
std::string argument = argv[1];
if(argument.substr(0, prefix.size()) == prefix) {
    std::string argumentValue = argument.substr(prefix.size());
}

2
सबसे संक्षिप्त और केवल std :: string पर निर्भर करता है, अंतिम रूट के अंत में वैकल्पिक और भ्रामक तर्क को हटा दें। (आकार)।
बेन ब्रायंट

@ बेन-ब्रायंट: सिर के लिए धन्यवाद। यह वैकल्पिक नहीं था।
हुसेन येल्लि

16
उपयोग substrकरने से अनावश्यक नकल होती है। str.compare(start, count, substr)में प्रयोग किया जाता विधि थॉमस 'जवाब और अधिक कुशल है। razvanco13 के जवाब में एक और तरीका है जिसका उपयोग करके नकल से बचा जाता है std::equal
फेलिक्स डोमबेक

4
@ HüseyinYağlı Thomas uses atoi which is only for windowsहुह? atoiकभी ... के बाद से एक सी मानक पुस्तकालय समारोह किया गया है। असल में, atoiनहीं है क्योंकि यह विंडोज-specific- लेकिन क्योंकि यह की (1) सी, नहीं सी ++, और (2) सी में भी पदावनत (आप का उपयोग करना चाहिए बुरा है strtolया अन्य संबंधित कार्यों में से एक। क्योंकि atoiहै कोई त्रुटि से निपटने। लेकिन, फिर से, यह केवल सी में है, वैसे भी)।
पार्थियन शॉट

50

किसी ने अभी तक एसटीएल एल्गोरिथ्म / बेमेल फ़ंक्शन का उपयोग नहीं किया। यदि यह सही है, तो उपसर्ग 'toCheck' का एक उपसर्ग है:

std::mismatch(prefix.begin(), prefix.end(), toCheck.begin()).first == prefix.end()

पूर्ण उदाहरण

#include <algorithm>
#include <string>
#include <iostream>

int main(int argc, char** argv) {
    if (argc != 3) {
        std::cerr << "Usage: " << argv[0] << " prefix string" << std::endl
                  << "Will print true if 'prefix' is a prefix of string" << std::endl;
        return -1;
    }
    std::string prefix(argv[1]);
    std::string toCheck(argv[2]);
    if (prefix.length() > toCheck.length()) {
        std::cerr << "Usage: " << argv[0] << " prefix string" << std::endl
                  << "'prefix' is longer than 'string'" <<  std::endl;
        return 2;
    }
    if (std::mismatch(prefix.begin(), prefix.end(), toCheck.begin()).first == prefix.end()) {
        std::cout << '"' << prefix << '"' << " is a prefix of " << '"' << toCheck << '"' << std::endl;
        return 0;
    } else {
        std::cout << '"' << prefix << '"' << " is NOT a prefix of " << '"' << toCheck << '"' << std::endl;
        return 1;
    }
}

संपादित करें:

जैसा कि @James T. Huggett बताते हैं, std :: बराबर सवाल के लिए एक बेहतर फिट है: A, B का उपसर्ग है? और मामूली छोटा कोड है:

std::equal(prefix.begin(), prefix.end(), toCheck.begin())

पूर्ण उदाहरण

#include <algorithm>
#include <string>
#include <iostream>

int main(int argc, char **argv) {
  if (argc != 3) {
    std::cerr << "Usage: " << argv[0] << " prefix string" << std::endl
              << "Will print true if 'prefix' is a prefix of string"
              << std::endl;
    return -1;
  }
  std::string prefix(argv[1]);
  std::string toCheck(argv[2]);
  if (prefix.length() > toCheck.length()) {
    std::cerr << "Usage: " << argv[0] << " prefix string" << std::endl
              << "'prefix' is longer than 'string'" << std::endl;
    return 2;
  }
  if (std::equal(prefix.begin(), prefix.end(), toCheck.begin())) {
    std::cout << '"' << prefix << '"' << " is a prefix of " << '"' << toCheck
              << '"' << std::endl;
    return 0;
  } else {
    std::cout << '"' << prefix << '"' << " is NOT a prefix of " << '"'
              << toCheck << '"' << std::endl;
    return 1;
  }
}

2
Std का उपयोग क्यों नहीं करते हैं :: बराबर?
ब्राइस एम। डेम्पसे

मुझे अच्छा लगता है। यह कम कोड भी होगा। मुझे लगता है, मुझे अब उत्तर को संपादित करना होगा: पी
मतिउ २१'१५

2
std::equalस्ट्रिंग्स के लिए उपयोग करने में नकारात्मक पक्ष यह है कि यह स्ट्रिंग अंत का पता नहीं लगाता है, इसलिए आपको मैन्युअल रूप से जांचने की आवश्यकता है कि क्या उपसर्ग पूरे स्ट्रिंग की तुलना में छोटा है या नहीं। (जैसा कि उदाहरण में सही ढंग से किया गया है, लेकिन ऊपर दिए गए एक-लाइनर में छोड़ दिया गया है।)
फेलिक्स डॉमबेक

तो, कोई लाभ rfind?
Андрей Вахрушев

26

यह देखते हुए कि दोनों तार - argv[1]और "--foo"- सी तार हैं, @ FelixDombek का जवाब हाथों-हाथ सबसे अच्छा समाधान है।

हालांकि, अन्य उत्तरों को देखकर, मुझे लगा कि यह ध्यान देने योग्य है कि, यदि आपका पाठ पहले से ही उपलब्ध है std::string, तो एक सरल, शून्य-प्रतिलिपि, अधिकतम कुशल समाधान मौजूद है जिसका अब तक उल्लेख नहीं किया गया है:

const char * foo = "--foo";
if (text.rfind(foo, 0) == 0)
    foo_value = text.substr(strlen(foo));

और अगर फू पहले से ही एक स्ट्रिंग है:

std::string foo("--foo");
if (text.rfind(foo, 0) == 0)
    foo_value = text.substr(foo.length());

6
rfind(x, 0) == 0वास्तव में मानक के रूप में परिभाषित किया जाना चाहिएstarts_with
porges

1
नहीं, क्योंकि rfind()(के स्थान पर startswith()) बहुत अक्षम है - यह स्ट्रिंग के अंत तक खोज करता रहता है।
एकॉस्टिस

4
@ankostis rfind (एक्स) शुरू से अंत तक खोजता है जब तक कि यह वास्तव में एक्स नहीं पाता है। लेकिन रिफ़्ड (x, 0) प्रारंभ से (स्थिति = 0) से प्रारंभ होने तक खोज करता है; इसलिए यह केवल वही खोजता है जहाँ इसे खोजने की आवश्यकता है; / से अंत तक खोज नहीं करता है।
अनाम कायर

18

C ++ 17 के साथ आप std::basic_string_viewC ++ 20 का उपयोग कर सकते हैं std::basic_string::starts_withया कर सकते हैं std::basic_string_view::starts_with

की std::string_viewतुलना में लाभ std::string- स्मृति प्रबंधन के बारे में - यह है कि यह केवल एक "स्ट्रिंग" के लिए एक संकेतक रखता है (चार्ट जैसी वस्तुओं का सन्निहित अनुक्रम) और इसके आकार को जानता है। उदाहरण केवल पूर्णांक मान प्राप्त करने के लिए स्रोत स्ट्रिंग्स को स्थानांतरित / कॉपी किए बिना:

#include <exception>
#include <iostream>
#include <string>
#include <string_view>

int main()
{
    constexpr auto argument = "--foo=42"; // Emulating command argument.
    constexpr auto prefix = "--foo=";
    auto inputValue = 0;

    constexpr auto argumentView = std::string_view(argument);
    if (argumentView.starts_with(prefix))
    {
        constexpr auto prefixSize = std::string_view(prefix).size();
        try
        {
            // The underlying data of argumentView is nul-terminated, therefore we can use data().
            inputValue = std::stoi(argumentView.substr(prefixSize).data());
        }
        catch (std::exception & e)
        {
            std::cerr << e.what();
        }
    }
    std::cout << inputValue; // 42
}

1
@ रोलैंडलीग नहीं, std::atoiपूरी तरह से ठीक है। यह खराब इनपुट (जो इस कोड में संभाला जाता है) पर अपवाद फेंकता है। क्या आपके मन में कुछ और था?
रूई डेंटन

आप के बारे में बात कर रहे हैं atoiसे <cstdlib>? प्रलेखन कहते हैं "यह अपवाद फेंकता है कभी नहीं।"
रोलैंड इलिग

@RolandIllig मैं आपकी पहली टिप्पणी की बात कर रहा हूं। ऐसा लगता है, आप गलती से atoiइसके बजाय के बारे में बात कर रहे हैं std::atoi। पहला उपयोग करने के लिए असुरक्षित है, जबकि बाद वाला ठीक है। मैं यहाँ कोड में बाद का उपयोग कर रहा हूँ।
रूई डेंटन

कृपया std::atoiउपयुक्त संदर्भ का हवाला देते हुए मुझे साबित करें कि वास्तव में एक अपवाद को फेंकता है। जब तक आप ऐसा नहीं करते, तब तक मैं आपको विश्वास नहीं दिलाता, क्योंकि यह पूरी तरह से अलग तरीके से ::atoiऔर std::atoiअभिनय दोनों के लिए बहुत भ्रामक होगा ।
रोलैंड इलिग

4
@ रोलैंडलीग लगातार बने रहने के लिए धन्यवाद! आप सही हैं, यह एक ऐसा निरीक्षण std::atoiथा जिसका उपयोग किया गया था std::stoi। मैंने तय कर लिया है।
रूई डेंटन

12
text.substr(0, start.length()) == start

3
@GregorDoroschenko यह "जाँच करता है कि क्या स्ट्रिंग दूसरे" भाग से शुरू होती है।
etarion

1
Std :: string का उपयोग करते हुए कुशल और सुरुचिपूर्ण। मैंने इससे सबसे ज्यादा सीखा।
माइकल बी

1
एक-लाइनर के साथ उपयोग के लिए उपयुक्त होने के लिए अतिरिक्त अंकif (one-liner)
Adam.at.Epsilon

@ रोलैंड इलिग आप क्यों मानते हैं कि उस मामले में व्यवहार अपरिभाषित है? एक्सप्रेशन के अनुसार टेक्स्ट के रूप में एक ही लेंथ की एक स्ट्रिंग के वापस आने पर एक्सप्रेशन गलत होगा क्योंकि en.cppreference.com/w/cpp/string/basic_string/substr
Macsinus

11

एसटीएल के प्रयोग से ऐसा लग सकता है:

std::string prefix = "--foo=";
std::string arg = argv[1];
if (prefix.size()<=arg.size() && std::equal(prefix.begin(), prefix.end(), arg.begin())) {
  std::istringstream iss(arg.substr(prefix.size()));
  iss >> foo_value;
}

2
वह होना चाहिए if (prefix.size()<=arg.size() && std::equal(...))
जारेड ग्रब

10

सी कंस्ट्रक्शंस का उपयोग करने के लिए फ़्लेम किए जाने के जोखिम पर, मुझे लगता है कि यह sscanfउदाहरण सबसे बूस्ट समाधानों की तुलना में अधिक सुरुचिपूर्ण है। और आपको लिंकेज के बारे में चिंता करने की ज़रूरत नहीं है अगर आप कहीं भी चल रहे हैं जिसमें पायथन दुभाषिया है!

#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
    for (int i = 1; i != argc; ++i) {
        int number = 0;
        int size = 0;
        sscanf(argv[i], "--foo=%d%n", &number, &size);
        if (size == strlen(argv[i])) {
            printf("number: %d\n", number);
        }
        else {
            printf("not-a-number\n");
        }
    }
    return 0;
}

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

$ ./scan --foo=2 --foo=2d --foo='2 ' ' --foo=2'
number: 2
not-a-number
not-a-number
not-a-number

7
यदि argv[i]है "--foo=9999999999999999999999999", तो व्यवहार अपरिभाषित है (हालांकि अधिकांश या सभी कार्यान्वयनों को पूरी तरह से व्यवहार करना चाहिए)। मैं मान रहा हूँ 9999999999999999999999999 > INT_MAX
कीथ थॉम्पसन

10

मैं std::string::compareनीचे की तरह उपयोगिता विधि में लिपटे का उपयोग करता हूं :

static bool startsWith(const string& s, const string& prefix) {
    return s.size() >= prefix.size() && s.compare(0, prefix.size(), prefix) == 0;
}

5

गन्नो के गोश्त का उपयोग क्यों नहीं करते? यहाँ एक बुनियादी उदाहरण है (सुरक्षा जांच के बिना):

#include <getopt.h>
#include <stdio.h>

int main(int argc, char** argv)
{
  option long_options[] = {
    {"foo", required_argument, 0, 0},
    {0,0,0,0}
  };

  getopt_long(argc, argv, "f:", long_options, 0);

  printf("%s\n", optarg);
}

निम्नलिखित आदेश के लिए:

$ ./a.out --foo=33

तुम्हे मिल जाएगा

33

5

यदि आपको C ++ 11 संगतता की आवश्यकता है और उपयोग को बढ़ावा नहीं दे सकता है, तो यहां उपयोग के उदाहरण के साथ बूस्ट-संगत ड्रॉप-इन है:

#include <iostream>
#include <string>

static bool starts_with(const std::string str, const std::string prefix)
{
    return ((prefix.size() <= str.size()) && std::equal(prefix.begin(), prefix.end(), str.begin()));
}

int main(int argc, char* argv[])
{
    bool usage = false;
    unsigned int foos = 0; // default number of foos if no parameter was supplied

    if (argc > 1)
    {
        const std::string fParamPrefix = "-f="; // shorthand for foo
        const std::string fooParamPrefix = "--foo=";

        for (unsigned int i = 1; i < argc; ++i)
        {
            const std::string arg = argv[i];

            try
            {
                if ((arg == "-h") || (arg == "--help"))
                {
                    usage = true;
                } else if (starts_with(arg, fParamPrefix)) {
                    foos = std::stoul(arg.substr(fParamPrefix.size()));
                } else if (starts_with(arg, fooParamPrefix)) {
                    foos = std::stoul(arg.substr(fooParamPrefix.size()));
                }
            } catch (std::exception& e) {
                std::cerr << "Invalid parameter: " << argv[i] << std::endl << std::endl;
                usage = true;
            }
        }
    }

    if (usage)
    {
        std::cerr << "Usage: " << argv[0] << " [OPTION]..." << std::endl;
        std::cerr << "Example program for parameter parsing." << std::endl << std::endl;
        std::cerr << "  -f, --foo=N   use N foos (optional)" << std::endl;
        return 1;
    }

    std::cerr << "number of foos given: " << foos << std::endl;
}

2

आप यह भी उपयोग कर सकते हैं strstr:

if (strstr(str, substr) == substr) {
    // 'str' starts with 'substr'
}

लेकिन मुझे लगता है कि यह केवल शॉर्ट स्ट्रिंग्स के लिए अच्छा है क्योंकि इसे पूरे स्ट्रिंग के माध्यम से लूप करना पड़ता है जब स्ट्रिंग वास्तव में 'रूट' से शुरू नहीं होती है।


2

ठीक है क्यों पुस्तकालयों और सामान का जटिल उपयोग? C ++ स्ट्रिंग ऑब्जेक्ट्स [] ऑपरेटर को अधिभारित करते हैं, इसलिए आप बस वर्णों की तुलना कर सकते हैं .. जैसे मैंने अभी किया, क्योंकि मैं सभी फाइलों को एक निर्देशिका में सूचीबद्ध करना चाहता हूं और अदृश्य फ़ाइलों और .. और को अनदेखा करना चाहता हूं। pseudofiles।

while ((ep = readdir(dp)))
{
    string s(ep->d_name);
    if (!(s[0] == '.')) // Omit invisible files and .. or .
        files.push_back(s);
}

यह इत्ना आसान है..


4
इतिहास का एक पाठ: plus.sandbox.google.com/+RobPikeTheHuman/posts/R58WgWwN9jp
robertwb

2
@robertwb Google+ अब उपलब्ध नहीं है
_Staticertassert

0
std::string text = "--foo=98";
std::string start = "--foo=";

if (text.find(start) == 0)
{
    int n = stoi(text.substr(start.length()));
    std::cout << n << std::endl;
}

3
यह बहुत अच्छा होगा, यदि आप कोड स्पष्टीकरण के बिना कोड चिपकाने से बचते हैं। धन्यवाद।
पुनर्जन्म

1
अक्षम कोड, स्ट्रिंग की शुरुआत में खोज जारी रखेगा।
एकॉस्टिस

0

C ++ 11 या उच्चतर के साथ आप उपयोग कर सकते हैं find() औरfind_first_of()

एकल चार को खोजने के लिए खोज का उपयोग करके उदाहरण:

#include <string>
std::string name = "Aaah";
size_t found_index = name.find('a');
if (found_index != std::string::npos) {
    // Found string containing 'a'
}

एक पूर्ण स्ट्रिंग खोजने के लिए उदाहरण का उपयोग करें और स्थिति 5 से शुरू करें:

std::string name = "Aaah";
size_t found_index = name.find('h', 3);
if (found_index != std::string::npos) {
    // Found string containing 'h'
}

find_first_of()केवल शुरुआत में खोज करने के लिए और केवल पहले चार का उपयोग करके उदाहरण :

std::string name = ".hidden._di.r";
size_t found_index = name.find_first_of('.');
if (found_index == 0) {
    // Found '.' at first position in string
}

सौभाग्य!


क्यों नहीं rfind? Rfind (str, 0) एक चयन करने के लिए पूरे स्ट्रिंग को अनावश्यक रूप से स्कैन नहीं करेगा क्योंकि यह आगे नहीं बढ़ सकता है। दूसरों को देखें।
user2864740

0

चूंकि C ++ 11 का std::regex_searchउपयोग मिलान के और भी अधिक जटिल भाव प्रदान करने के लिए भी किया जा सकता है। निम्नलिखित उदाहरण भी तैरती संख्या वक्ष std::stofऔर बाद के कलाकारों को संभालता हैint

हालाँकि parseIntनीचे दी गई विधि एक std::invalid_argumentअपवाद को फेंक सकती है यदि उपसर्ग का मिलान नहीं होता है; यह दिए गए आवेदन के आधार पर आसानी से अनुकूलित किया जा सकता है:

#include <iostream>
#include <regex>

int parseInt(const std::string &str, const std::string &prefix) {
  std::smatch match;
  std::regex_search(str, match, std::regex("^" + prefix + "([+-]?(?=\\.?\\d)\\d*(?:\\.\\d*)?(?:[Ee][+-]?\\d+)?)$"));
  return std::stof(match[1]);
}

int main() {
    std::cout << parseInt("foo=13.3", "foo=") << std::endl;
    std::cout << parseInt("foo=-.9", "foo=") << std::endl;
    std::cout << parseInt("foo=+13.3", "foo=") << std::endl;
    std::cout << parseInt("foo=-0.133", "foo=") << std::endl;
    std::cout << parseInt("foo=+00123456", "foo=") << std::endl;
    std::cout << parseInt("foo=-06.12e+3", "foo=") << std::endl;

//    throw std::invalid_argument
//    std::cout << parseInt("foo=1", "bar=") << std::endl;

    return 0;
}

रेगेक्स पैटर्न का जादू निम्नलिखित उत्तर में अच्छी तरह से विस्तृत है ।

संपादित करें: पिछले उत्तर ने पूर्णांक में रूपांतरण नहीं किया था।


0

C ++ 20 से शुरू करके, आप starts_withविधि का उपयोग कर सकते हैं ।

std::string s = "abcd";
if (s.starts_with("abc")) {
    ...
}

-3
if(boost::starts_with(string_to_search, string_to_look_for))
    intval = boost::lexical_cast<int>(string_to_search.substr(string_to_look_for.length()));

यह पूरी तरह से अप्रयुक्त है। सिद्धांत पायथन एक के समान है। Boost.StringAlgo और Boost.LexicalCast की आवश्यकता है।

जांचें कि क्या स्ट्रिंग दूसरे स्ट्रिंग से शुरू होती है, और फिर पहले स्ट्रिंग के प्रतिस्थापन ('स्लाइस') प्राप्त करें और इसे लेक्सिकल कास्ट का उपयोग करके परिवर्तित करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.