একটি সি ++ এসডিডি :: স্ট্রিংটি একটি নির্দিষ্ট স্ট্রিং দিয়ে শুরু হয় কিনা এবং কীভাবে আমি একটি স্ট্রিংকে একটি ইনটে রূপান্তর করতে পারি তা আমি কীভাবে চেক করব?


242

আমি কীভাবে সি ++ এ নিম্নলিখিত (পাইথন সিউডোকোড) প্রয়োগ করব?

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

(উদাহরণস্বরূপ, যদি argv[1]হয় --foo=98, তবে foo_valueহয় 98))

আপডেট: আমি বুস্টের দিকে নজর দিতে দ্বিধা বোধ করছি, যেহেতু আমি কেবল একটি সাধারণ ছোট কমান্ড-লাইন সরঞ্জামে খুব ছোট পরিবর্তন আনতে দেখছি (অপ্রাপ্তবয়স্কের জন্য কীভাবে সংযুক্ত করতে এবং বুস্টকে ব্যবহার করতে হয় তা শিখতে হবে না) পরিবর্তন).


এই এছাড়াও আকর্ষণীয়।
মানিলিও

উত্তর:


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
এই উত্তরটি সবচেয়ে বেশি ভোট দেওয়া উচিত বুস্টটি নয়: ডি যখন আপনার ইতিমধ্যে এসটিএল রয়েছে তখন অন্য লাইব্রেরি কেন ব্যবহার করবেন।
Iuliu Atudosiei

@ সুইজারবার.দেব, আমি আপনার প্রথম বিতর্ক নিয়ে বিভ্রান্ত। থেকে ফেরত মান findইচ্ছার শুধুমাত্র শূন্য হতে যদি titiশুরু স্ট্রিং এর। যদি এটি অন্য কোথাও পাওয়া যায়, আপনি একটি শূন্য-না ফেরতের মান পাবেন এবং যদি এটি খুঁজে না পাওয়া যায় তবে আপনি nposযা শূন্য-তেও পাবেন । আমি সঠিক বলে ধরে নিচ্ছি, আমি এই উত্তরটি পছন্দ করব যেহেতু আমাকে কোনও মানহীন স্টাফ আনতে হবে না (হ্যাঁ, আমি জানি বুস্ট সর্বত্র রয়েছে, আমি এই জাতীয় সরল সামগ্রীর জন্য কেবল সি সি ++ লিবস পছন্দ করব)।
প্যাক্সিডিয়াবলো

@ প্যাক্সিয়াব্লো: আপনি ঠিক বলেছেন, এটি শুরু হয় কিনা তা সত্যই যাচাই করে তবে titiরূপান্তর অংশটি অনুপস্থিত।
সুইজারবার.দেব

2
আমাদের কাছে কি কোনও প্রমাণ আছে যে এটি বেশিরভাগ সংকলকগুলিতে অনুকূলিত হয়েছে? আমি অন্য কোথাও "ফাইন্ড" বা "আরফাইন্ড" অপ্টিমাইজেশনের উল্লেখ করাই প্রত্যাবর্তন মূল্যের উপর ভিত্তি করে যা দেখছি তার উপর ভিত্তি করে সাধারণ অনুশীলন।
সুপারজিআই

2
@alcoforado "rfind স্ট্রিং এর পিছন থেকে শুরু হবে ..." না, এটি কেবলমাত্র পরামিতি rfind()নেয় না এর ওভারলোডের জন্য প্রযোজ্য pos। যদি আপনি ওভারলোড ব্যবহার করেন যা কোনও posপরামিতি নেয় তবে এটি পুরো স্ট্রিংটি অনুসন্ধান করবে না, কেবল সেই অবস্থান এবং তার আগে। (যেমন প্যারামিটারের find()সাথে নিয়মিত posকেবল সেই পজিশনে বা তার পরে দেখায় you) সুতরাং আপনি pos == 0যদি এই উত্তরে দেখানো হিসাবে পাস করেন তবে এটি আক্ষরিক অর্থে কেবলমাত্র সেই এক পজিশনের ম্যাচগুলির জন্য বিবেচনা করবে। এটি ইতিমধ্যে উত্তর এবং মন্তব্য উভয়ই ব্যাখ্যা ছিল।
আর্থার টাক্কা

188

আপনি এটি এইভাবে করতে হবে:

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

বুস্ট.প্রগ্রামঅ্যাপশনগুলির মতো একটি লাইব অনুসন্ধান করা যা এটি আপনার জন্য করে এটিও একটি ভাল ধারণা।


7
এটির সাথে সবচেয়ে বড় সমস্যাটি হ'ল atoi("123xyz")প্রত্যাবর্তন 123, যেখানে পাইথনের int("123xyz")ব্যতিক্রম ছোঁড়ে।
টম

যে কাজটি আমরা করতে পারি, তা হ'ল একটি স্ক্যানফ () এবং ফলাফল এবং মূলটির সাথে তুলনা করে এগিয়ে যাওয়া বা ব্যতিক্রম ছুঁড়ে ফেলার সিদ্ধান্ত নেওয়া।
রূপেশ মাজেতি

1
অথবা শুধু প্রতিস্থাপন atoiসঙ্গে strtolবা strtollযা আমাদের ইনপুট মান ত্রুটি অবস্থা নির্ণয় করতে দেয়।
টম

1
এটি rfindকাজের অপ্টিমাইজেশনের উপর নির্ভর করে তার থেকে এটি আরও ভাল সমাধান ।
কলমারিয়াস

143

কেবল সম্পূর্ণতার জন্য, আমি এটি করার সি উপায় উল্লেখ করব:

যদি strআপনার আসল স্ট্রিং substrহয় তবে আপনি যে সাবস্ট্রিংটি পরীক্ষা করতে চান তা কি

strncmp(str, substr, strlen(substr))

শুরু 0হলে ফিরে আসবে । ফাংশন এবং সি শিরোনাম ফাইল হয়strsubstrstrncmpstrlen<string.h>

(মূলত ইয়াসিন রউফ এখানে পোস্ট করেছেন , মার্কআপ যুক্ত হয়েছে)

কেস-সংবেদনশীল তুলনার জন্য strnicmpপরিবর্তে ব্যবহার করুন strncmp

এটি করার এটিই সি উপায়, সি ++ স্ট্রিংগুলির জন্য আপনি একই ফাংশনটি ব্যবহার করতে পারেন:

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

9
প্রকৃতপক্ষে, সবাই মনে হয় "ব্যবহার বাড়ান" এবং আমি একজনের জন্য একটি স্টিল বা ওএস লাইব্রেরি সংস্করণের জন্য কৃতজ্ঞ
ফোর্স গাইয়া

হ্যাঁ. তবে এটি ধরে নেয় স্ট্রিংটির কোনও নাল অক্ষর নেই। যদি এটি না হয় - একটি ব্যবহার করা উচিতmemcmp()
অবিশাই ওয়াই

কেন কেউ এই সাধারণ সুন্দর সমাধান ব্যতীত অন্য কিছু ব্যবহার করবে?
আদম জহরান

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
}

এই ধরণের পদ্ধতির যেমন এখানে সরবরাহিত অন্যান্য উত্তরগুলির মতো খুব সাধারণ কাজের জন্য ঠিক আছে তবে দীর্ঘমেয়াদে আপনি সাধারণত একটি কমান্ড লাইন পার্সিং লাইব্রেরি ব্যবহার করে ভাল হন। বুস্টের একটি ( বুস্ট.প্রগ্রাম_অপশন ) রয়েছে, যা আপনি যদি ইতিমধ্যে বুস্ট ব্যবহার করে থাকেন তবে তা বোধগম্য হতে পারে।

অন্যথায় "c ++ কমান্ড লাইন পার্সার" অনুসন্ধানের ফলে অনেকগুলি বিকল্প পাওয়া যাবে।


107
স্ট্রিং উপসর্গের চেকের জন্য বিশাল নির্ভরতার দিকে টানানো ক্যানন সহ পাখিদের শুটিংয়ের মতো।
টোবি

150
যখন কেউ সি ++ এ কীভাবে একটি সাধারণ স্ট্রিং অপারেশন করবেন তা জিজ্ঞাসা করলে "ইউজ বুস্ট" সর্বদা ভুল উত্তর is
গ্লেন মেইনার্ড

90
বুস্টের পরামর্শের জন্য বিয়োগ 1
uglycoyote

37
আপনি যদি ইতিমধ্যে আপনার প্রকল্পে বুস্ট ব্যবহার করেন তবে এখানে বুস্ট ব্যবহার করা ঠিক।
অ্যালেক্স চে

17
উত্তরটি "আপনি যদি বুস্ট ব্যবহার করছেন ..." দিয়ে উপসর্গযুক্ত। স্পষ্টতই এটি সঠিক উত্তর "... যদি আপনি বুস্ট ব্যবহার করেন"। যদি তা না হয় তবে
@ থমাসের

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
চূড়ান্ত সাবস্ট্রারের শেষে alচ্ছিক এবং বিভ্রান্তিমূলক আর্গুমেন্ট.সাইজ () সরিয়ে ব্যতীত সর্বাধিক সংক্ষিপ্ত এবং শুধুমাত্র স্টাডি :: স্ট্রিংয়ের উপর নির্ভর করে।
বেন ব্রায়ান্ট

@ বেন-ব্রায়ান্ট: মাথা উঁচু করার জন্য ধন্যবাদ। জানেন না এটি optionচ্ছিক।
Hyseyin Yağlı

16
substrঅপ্রয়োজনীয় অনুলিপি ব্যবহার করে । str.compare(start, count, substr)ব্যবহৃত পদ্ধতি টমাস 'উত্তর আরও দক্ষ নয়। razvanco13 এর উত্তরে অন্য একটি পদ্ধতি রয়েছে যা ব্যবহার করে অনুলিপি করা এড়ায়std::equal
ফেলিক্স ডোমব্যাক

4
@ হেসেইনইয়াল্ল Thomas uses atoi which is only for windowsহাহ? atoiতখন থেকেই সি স্ট্যান্ডার্ড লাইব্রেরি ফাংশন হয়ে আসছে। সত্যিকার অর্থে, atoiএটি খারাপ- কারণ এটি উইন্ডোজ-নির্দিষ্ট নয়- তবে এটি (1) সি, সি ++ নয়, এবং (2) এমনকি সি-তে অবমূল্যায়ন করেছে (আপনার ব্যবহার করা উচিত strtolবা অন্য যে কোনও একটি সম্পর্কিত সম্পর্কিত ফাংশন) কারণ atoiরয়েছে কোনও ত্রুটি পরিচালনায় কোনও সমস্যা নেই But তবে, এটি কেবলমাত্র সি তে, যাইহোক।
পার্থিয়ান শট

50

কেউ এখনও এসটিএল অ্যালগরিদম / মেলে না ফাংশন ব্যবহার । যদি এটি সত্য হয়, উপসর্গটি 'টু চেক' এর উপসর্গ:

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

সম্পাদনা:

@ জেমস টি। হুগেটের পরামর্শ অনুসারে, স্টাড :: সমান প্রশ্নের জন্য আরও ভাল ফিট: একটি বি এর উপসর্গ কি? এবং সামান্য সংক্ষিপ্ত কোড:

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
স্টাড :: সমান ব্যবহার করবেন না কেন?
ব্রাইস এম। ড্যাম্পসে

আমার ভাল লাগছে। এটিও সংক্ষিপ্ত কোড হবে। আমি মনে করি, আমাকে এখনই উত্তরটি সম্পাদনা করতে হবে: p
matiu

2
ব্যবহার std::equalস্ট্রিং জন্য downside হয় যে এটা এত আপনি নিজে কি না চেক করতে উপসর্গ পুরো স্ট্রিং চেয়ে খাটো প্রয়োজন স্ট্রিং শেষ শনাক্ত করতে পারছে না আছে। (উদাহরণস্বরূপ, উদাহরণস্বরূপ সঠিকভাবে করা হয়েছে, তবে উপরের ওয়ান-লাইনারে বাদ দেওয়া হয়েছে))
ফেলিক্স ডমব্যাক

সুতরাং, rfind উপর কোন লাভ?
16 Вахрушев

26

উভয় স্ট্রিং - argv[1]এবং "--foo"- সি স্ট্রিং দেওয়া হয়েছে, @ ফেলিক্সডমব্যাকের উত্তর হ'ল সেরা সমাধান।

অন্যান্য উত্তরগুলি দেখে তবে আমি মনে করি এটি লক্ষ্য করার মতো যে, যদি আপনার পাঠ্যটি ইতিমধ্যে একটি হিসাবে উপলব্ধ থাকে std::stringতবে একটি সাধারণ, শূন্য অনুলিপি, সর্বাধিক দক্ষ সমাধান রয়েছে যা এখনও অবধি উল্লেখ করা হয়নি:

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

এবং যদি 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()) খুব অদক্ষ - এটি স্ট্রিংয়ের শেষ অবধি অনুসন্ধান চালিয়ে যায়।
ankostis

4
@ঙ্কোস্টিস আরফাইন্ড (এক্স) শেষ থেকে শুরু পর্যন্ত এটি এক্স না পাওয়া অবধি অনুসন্ধান করে। তবে আরফাইন্ড (x, 0) শুরু থেকে অনুসন্ধান (অবস্থান = 0) শুরু করে; সুতরাং এটি কেবল যেখানে অনুসন্ধান দরকার সেখানে অনুসন্ধান করে; শেষ থেকে / শেষ পর্যন্ত অনুসন্ধান করে না।
বেনামী কোঅর্দ

18

সি ++ 17 এর মাধ্যমে আপনি std::basic_string_viewসি ++ 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>? ডকুমেন্টেশন বলছেন "এটা ব্যতিক্রম ছোঁড়ার কখনো"।
রোল্যান্ড ইলিগ

@ রোল্যান্ডইলিগ আমি আপনার প্রথম মন্তব্যে উল্লেখ করছি। দেখে মনে হচ্ছে আপনি এর atoiপরিবর্তে ভুল করে কথা বলছেন std::atoi। প্রথমটি ব্যবহার করা অনিরাপদ, যখন শেষটি ভাল। আমি এখানে কোডটি পরে ব্যবহার করছি।
রুই ড্যান্টন

std::atoiএকটি উপযুক্ত রেফারেন্স উদ্ধৃত করে দয়া করে আমাকে প্রমাণ করুন যে সত্যই একটি ব্যতিক্রম ছুঁড়েছে। যতক্ষণ না আপনি না করেন ততক্ষণ আমি আপনাকে বিশ্বাস করি না যেহেতু উভয়কে রাখা ::atoiএবং std::atoiসম্পূর্ণ ভিন্ন উপায়ে অভিনয় করা খুব বিভ্রান্তিকর হবে ।
রোল্যান্ড ইলিগ

4
নিরবচ্ছিন্ন থাকার জন্য @ রোল্যান্ডইলিগ ধন্যবাদ! আপনি ঠিক বলেছেন, এটি একটি তদারকি std::atoiছিল যা তার পরিবর্তে ব্যবহৃত হয়েছিল std::stoi। আমি এটা ঠিক করেছি।
রুই ড্যান্টন

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

3
@ গ্রেগরডোরোশেঙ্কো এটি "অংশটি অন্য একটি দিয়ে শুরু হয় কিনা" তা পরীক্ষা করে উত্তর দেয়।
ইটারিওন

1
স্ট্যান্ড :: স্ট্রিং ব্যবহার করে দক্ষ এবং মার্জিত। আমি এ থেকে সবচেয়ে বেশি শিখেছি।
মাইকেল বি

1
ওয়ান-লাইনারের সাথে ব্যবহারের জন্য উপযুক্ত হওয়ার জন্য অতিরিক্ত পয়েন্টগুলিif (one-liner)
আদম.এট.এপসিলন

@ রোল্যান্ড ইলিগ আপনি কেন বিশ্বাস করেন যে এই ক্ষেত্রে আচরণটি অপরিজ্ঞাত? এক্সপ্রেশনটি মিথ্যা হিসাবে প্রত্যাবর্তন করবে কারণ সাবস্ট্রাস্ট এনএনপ্রেফারেন্স / ডাব্লু / সিপি / স্ট্রিং / বেসিক_স্ট্রিং
সুব্রাস্ট্র

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

Gnu getopts ব্যবহার করবেন না কেন? এখানে একটি প্রাথমিক উদাহরণ (সুরক্ষা চেক ব্যতীত):

#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

আপনার যদি সি ++ 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

ঠিক আছে কেন লাইব্রেরি এবং স্টাফের জটিল ব্যবহার? সি ++ স্ট্রিং অবজেক্টগুলি [] অপারেটরটিকে ওভারলোড করে, তাই আপনি কেবল অক্ষরের তুলনা করতে পারেন .. আমি যা করেছি ঠিক তার মতোই, কারণ আমি একটি ডিরেক্টরিতে সমস্ত ফাইল তালিকাভুক্ত করতে চাই এবং অদৃশ্য ফাইল এবং উপেক্ষা করতে চাই .. এবং। 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
@ আরবার্টবিবি Google+ এখন আর উপলভ্য নয়
_স্ট্যাটিক পোস্ট

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
অপ্রয়োজনীয় কোড, স্ট্রিংটির শুরুতে অতীতে অনুসন্ধান চালিয়ে যাবে।
ankostis

0

সি ++ 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
}

শুভকামনা!


রিফাইন্ড কেন? আরফাইন্ড (টিআর, 0) অকারণে বাছাই করতে পুরো স্ট্রিংটি স্ক্যান করবে না কারণ এটি অগ্রসর হতে পারে না। অন্যদের দেখুন।
ব্যবহারকারী 2864740

0

যেহেতু সি ++ 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

সি ++ 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 এর দরকার।

স্ট্রিংটি অন্য স্ট্রিংয়ের সাথে শুরু হয় কিনা তা পরীক্ষা করে দেখুন এবং তারপরে প্রথম স্ট্রিংয়ের সাবস্ট্রিং ('স্লাইস') পান এবং লেক্সিকাল কাস্ট ব্যবহার করে রূপান্তর করুন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.