我如何在c++中实现以下(Python伪代码)?

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

(例如,如果argv[1]是——foo=98,那么foo_value是98。)

更新:我很犹豫是否要研究Boost,因为我只是想对一个简单的小命令行工具做一个非常小的改变(我宁愿不学习如何链接并使用Boost进行一个小的改变)。


当前回答

为了完整起见,我将提到C的方法:

如果str是你的原始字符串,substr就是你想要的子字符串 检查,然后 Strncmp (str, substr, strlen(substr)) 将返回0如果STR 从substr开始。函数strncmp和strlen在C 头文件<string.h>

(最初由Yaseen Rauf在这里发布,添加了标记)

对于不区分大小写的比较,请使用strnicmp而不是strncmp。

这是C语言的方法,对于c++的字符串,你可以像这样使用相同的函数:

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

其他回答

你会这样做:

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

寻找一个库,如Boost。为你做这件事的ProgramOptions也是一个好主意。

你也可以使用strstr:

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

但我认为它只适用于短字符串,因为当字符串实际上不是以'substr'开头时,它必须遍历整个字符串。

在c++ 20中,starts_with作为std::string的成员函数可用,定义为:

constexpr bool starts_with(string_view sv) const noexcept;

constexpr bool starts_with(CharT c) const noexcept;

constexpr bool starts_with(const CharT* s) const;

所以你的代码可以是这样的:

std::string s{argv[1]};

if (s.starts_with("--foo="))

我自己使用的代码:

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

在c++ 17中,你可以使用std::basic_string_view,在c++ 20中使用std::basic_string::starts_with或std::basic_string_view::starts_with。

std::string_view与std::string相比的好处是——关于内存管理——它只保存一个指向“字符串”(连续的char类对象序列)的指针,并且知道它的大小。示例:不移动/复制源字符串,只获取整数值:

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