我如何在c++中实现以下(Python伪代码)?
if argv[1].startswith('--foo='):
foo_value = int(argv[1][len('--foo='):])
(例如,如果argv[1]是——foo=98,那么foo_value是98。)
更新:我很犹豫是否要研究Boost,因为我只是想对一个简单的小命令行工具做一个非常小的改变(我宁愿不学习如何链接并使用Boost进行一个小的改变)。
我如何在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())
其他回答
text.substr(0, start.length()) == start
还没有人使用STL算法/错配函数。如果返回true, prefix是'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::equal更适合回答这个问题: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;
}
}
在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
}
在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="))
c++ 20更新:
使用std:: string:: starts_with
https://en.cppreference.com/w/cpp/string/basic_string/starts_with
std::string str_value = /* smthg */;
const auto starts_with_foo = str_value.starts_with(std::string_view{"foo"});