Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何检查C++;string以某个字符串开始,并将子字符串转换为int? 如何在C++中实现以下(Python伪代码)?< /P>_C++_String_Parsing_Substring_Startswith - Fatal编程技术网

如何检查C++;string以某个字符串开始,并将子字符串转换为int? 如何在C++中实现以下(Python伪代码)?< /P>

如何检查C++;string以某个字符串开始,并将子字符串转换为int? 如何在C++中实现以下(Python伪代码)?< /P>,c++,string,parsing,substring,startswith,C++,String,Parsing,Substring,Startswith,(例如,如果argv[1]为--foo=98,则foo\u值为98) 更新:我不太想研究Boost,因为我只是想对一个简单的小命令行工具做一个很小的改动(我不想为了一个小改动而学习如何链接和使用Boost)。如果你已经在使用Boost,你可以用+ #包括 #包括 试试{ if(boost::以(argv[1],“--foo=”)开头) foo_value=boost::lexical_cast(argv[1]+6); }捕获(boost::错误的\u词汇\u投射){ //坏参数 } 与这里提供

(例如,如果
argv[1]
--foo=98
,则
foo\u值
98


更新:我不太想研究Boost,因为我只是想对一个简单的小命令行工具做一个很小的改动(我不想为了一个小改动而学习如何链接和使用Boost)。

如果你已经在使用Boost,你可以用+

#包括
#包括
试试{
if(boost::以(argv[1],“--foo=”)开头)
foo_value=boost::lexical_cast(argv[1]+6);
}捕获(boost::错误的\u词汇\u投射){
//坏参数
}
与这里提供的许多其他答案一样,这种方法对于非常简单的任务来说是可行的,但从长远来看,您通常最好使用命令行解析库。Boost有一个(),如果您碰巧已经在使用Boost,这可能是有意义的


否则,搜索“c++命令行解析器”将产生许多选项。

您可以这样做:

std::string prefix("--foo=");
if (!arg.compare(0, prefix.size(), prefix))
    foo_value = std::stoi(arg.substr(prefix.size()));
strncmp(str.c_str(), substr.c_str(), substr.size())
std::string s{argv[1]};

if (s.starts_with("--foo="))
寻找像Boost.ProgramOptions这样的库也是一个好主意。

if(Boost::以(string\u to\u search,string\u to\u look\u)开头)
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()));
intval=boost::词法转换(string-to-search.substr(string-to-look-for.length());
这完全没有经过测试。其原理与Python相同。需要Boost.StringAlgo和Boost.LexicalCast


检查字符串是否以另一个字符串开头,然后获取第一个字符串的子字符串(“切片”),并使用词法转换将其转换。

冒着使用C结构而被激怒的风险,我确实认为这个
sscanf
示例比大多数Boost解决方案更优雅。如果你在任何有Python解释器的地方运行,你就不必担心链接了

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

好吧,为什么图书馆和其他东西的使用如此复杂?C++字符串对象重载[]操作符,因此您可以比较字符。就像我刚才做的,因为我想列出目录中的所有文件,忽略不可见的文件和。。和。伪文件

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

就这么简单。

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

如果
str
是您的原始字符串,
substr
是您想要的子字符串 那就检查一下

strncmp(str,substr,strlen(substr))

如果
str
substr
开头。函数
strncmp
strlen
在C中 头文件

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

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

这是C的方式,对于C++字符串,你可以使用同样的函数:

std::string prefix("--foo=");
if (!arg.compare(0, prefix.size(), prefix))
    foo_value = std::stoi(arg.substr(prefix.size()));
strncmp(str.c_str(), substr.c_str(), substr.size())
std::string s{argv[1]};

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

使用STL,这可能看起来像:

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;
}
std::string prefix=“--foo=”;
std::string arg=argv[1];
if(prefix.size()>foo_值;
}
我自己使用的代码:

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

您还可以使用strstr
str

if (strstr(str, substr) == substr) {
    // 'str' starts with 'substr'
}
但我认为它只适用于短字符串,因为当字符串实际上不是以“substr”开头时,它必须循环整个字符串。

还没有人使用STL函数。如果返回true,则前缀是“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;
    }
}
#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;
  }
}
完整示例程序:

#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;
    }
}
#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;
  }
}
#包括
#包括
#包括
int main(int argc,字符**argv){
如果(argc!=3){

为什么不使用gnu getopts?下面是一个基本示例(没有安全检查):

你会得到

33

考虑到字符串--
argv[1]
和--foo
都是C字符串,这是最好的解决方案

但是,看到其他答案后,我认为值得注意的是,如果您的文本已经以
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());
使用具有
pos
参数的重载:

std::string s = "tititoto";
if (s.rfind("titi", 0) == 0) {
  // s starts with prefix
}
谁还需要什么?纯STL

许多人误读了这一点,认为这意味着“向后搜索整个字符串以查找前缀”。这将产生错误的结果(例如,
string(“tititito”)。rfind(“titi”)
返回2,因此与
==0
相比,返回false),并且效率低下(查看整个字符串而不是开始)。但它不会这样做,因为它将
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)
std::string text=“--foo=98”;
std::string start=“--foo=”;
if(text.find(start)==0)
{
intn=stoi(text.substr(start.length());

std::cout我使用
std::string::compare
包装在实用方法中,如下所示:

static bool startsWith(const string& s, const string& prefix) {
    return s.size() >= prefix.size() && s.compare(0, prefix.size(), prefix) == 0;
}
使用C++17,您可以使用&C++20或

在内存管理方面,
std::string\u视图
std::string
相比的好处在于,它只保存指向“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
}
#包括
#包括
#包括
#包括
int main()
{
constexpr auto-argument=“--foo=42”;//模拟命令参数。
constexpr auto prefix=“--foo=”;
自动输入值=0;
constexpr auto argumentView=std::string_视图(参数);
if(argumentView.start_以(前缀))
{
constexpr auto prefixSize=std::string_视图(prefix).size();
尝试
{
//argumentView的底层数据以nul结尾,因此我们可以使用data()。
inputValue=std::stoi(argumentView.substr(prefixSize.data());
}
捕获(标准::异常&e)
{
std::cerr因为也可以使用C++11
text.substr(0, start.length()) == start
#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
}
#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;
}
#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;
}
#include <string>
std::string name = "Aaah";
size_t found_index = name.find('a');
if (found_index != std::string::npos) {
    // Found string containing 'a'
}
std::string name = "Aaah";
size_t found_index = name.find('h', 3);
if (found_index != std::string::npos) {
    // Found string containing 'h'
}
std::string name = ".hidden._di.r";
size_t found_index = name.find_first_of('.');
if (found_index == 0) {
    // Found '.' at first position in string
}
std::string s = "abcd";
if (s.starts_with("abc")) {
    ...
}
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="))