【问题标题】:how to check string start in C++如何在 C++ 中检查字符串的开头
【发布时间】:2011-11-11 14:06:21
【问题描述】:

在 C++ 中有什么方法可以检查字符串是否以某个字符串开头(小于原始字符串)?就像我们在 Java 中可以做的那样

bigString.startswith(smallString);

【问题讨论】:

  • 你说的是C字符串还是std::String
  • 我说的是 C++ string.std::string

标签: c++ string


【解决方案1】:
std::string s("Hello world");

if (s.find("Hello") == 0)
{
    std::cout << "String starts with Hello\n";
}

【讨论】:

  • 我认为正则表达式对于这种简单的检查来说是一个糟糕的选择,请参阅我的回答,了解我认为这是解决此问题的有效方法。或者更好的 Alan Stokes 回复 string::compare()。
  • 一个有效的解决方案应该是O(min(bigString.length(), smallString.length()))
  • @sufyansiddique 很简单,是的。有效,不是很有效。如果smallString 不长于bigString,则只需比较前smallString.size() 个字符即可知道答案;除了在初始位置之外,您不必搜索整个 bigString 以查找 smallString
  • 正如其他人评论的那样,如果您要搜索的字符串很长并且您要查找的字符串很短,这不是一个非常有效的想法。当您只对开头的位感兴趣时,为什么要遍历整个字符串?
  • 如果“Hello”出现在最后还是中间怎么办?我认为这个程序应该找到任何出现的特定子字符串,而不是“以”开头。我认为提升字符串算法是一个不错的选择。参考stackoverflow.com/questions/1878001/…
【解决方案2】:

您可以使用string::compare() 执行此操作,它提供了用于比较两个字符串的全部或部分的各种选项。此版本将smallStringbigString 的适当大小前缀进行比较(如果bigStringsmallString 短,则可以正常工作):

bigString.compare(0, smallString.length(), smallString) == 0

我倾向于将其封装在一个名为 startsWith() 的免费函数中,否则它看起来会有点神秘。

更新:C++20 is adding 新增 starts_withends_with 函数,因此您最终将能够只编写 bigString.starts_with(smallString)

【讨论】:

    【解决方案3】:

    使用string::find()string::substr() 的方法不是最优的,因为它们要么复制你的字符串,要么在字符串的开头搜索多个匹配项。在您的情况下,这可能不是问题,但如果是,您可以使用 std::equal 算法。记得检查“干草堆”至少和“针”一样长。

    #include <string>    
    
    using namespace std;
    
    bool startsWith(const string& haystack, const string& needle) {
        return needle.length() <= haystack.length() 
            && equal(needle.begin(), needle.end(), haystack.begin());
    }
    

    【讨论】:

      【解决方案4】:

      一如既往,正确的解决方案来自 Boost:boost::algorithm::starts_with

      【讨论】:

      • 为了完成这个简单的任务而使用 boost 太糟糕了。
      • @Borzh,当然,你已经在你的项目中大量使用 Boost,为什么不这样做呢?
      • 不是每个人都使用 boost。下载它,把它放在存储库中只是为了使用starts_with()有点夸张。也许你应该考虑删除“正确的解决方案,一如既往......”。它既不是“正确”也不是“总是”。
      • 我和阿瓦卡在一起。在我看来,这正确的解决方案。顺便说一句,你必须包括 boost/algorithm/string.hpp
      • 同意 Borzh。并非所有项目都使用 boost(远非如此),因此“总是”和“正确”的词不属于这里。将这种怪物添加到 STL 或简单 strcmp 可以工作的项目中是疯狂的。
      【解决方案5】:

      稍微优化一下:

      if ( smallString.size() <= bigString.size() &&
           strncmp( smallString.c_str(), bigString.c_str(), smallString.length() ) == 0 )
      

      别忘了#include &lt;cstring&gt;#include &lt;string.h&gt;

      【讨论】:

        【解决方案6】:

        对于 C++20,您可以使用 std::basic_string::starts_with(或 std::basic_string_view::starts_with):

        #include <string_view>
        
        std::string_view bigString_v("Winter is gone"); // std::string_view avoids the copy in substr below.
        std::string_view smallString_v("Winter");
        if (bigString_v.starts_with(smallString_v))
        {
            std::cout << "Westeros" << bigString_v.substr(smallString_v.size());
        }
        

        【讨论】:

          【解决方案7】:

          最简单的方法是:

          if ( smallString.size() <= bigString.size()
              && std::equals( smallString.begin(), smallString.end(), bigString.end() )
          

          (如果两者之一或两者都是向量,这也将起作用。或任何 其他标准容器类型。)

          【讨论】:

          • -1 1) 我找不到任何 std::equals。你的意思是 std::equal 吗? 2) 你确定使用 bigString.end() - 人们会期待 bigString.begin() 吗? 3) Kleist 之前发布的答案似乎完全正确
          • 是的,两者都是。是std::equal,应该是bigString.end()
          【解决方案8】:

          strstr() 返回指向字符串中第一次出现的字符串的指针。

          【讨论】:

            【解决方案9】:

            我认为发布一个不使用任何库函数的原始解决方案是有意义的......

            // Checks whether `str' starts with `start'
            bool startsWith(const std::string& str, const std::string& start) {
                if (&start == &str) return true; // str and start are the same string
                if (start.length() > str.length()) return false;
                for (size_t i = 0; i < start.length(); ++i) {
                    if (start[i] != str[i]) return false;
                }
                return true;
            }
            

            添加一个简单的std::tolower 我们可以使这个不区分大小写

            // Checks whether `str' starts with `start' ignoring case
            bool startsWithIgnoreCase(const std::string& str, const std::string& start) {
                if (&start == &str) return true; // str and start are the same string
                if (start.length() > str.length()) return false;
                for (size_t i = 0; i < start.length(); ++i) {
                    if (std::tolower(start[i]) != std::tolower(str[i])) return false;
                }
                return true;
            }
            

            【讨论】:

              【解决方案10】:

              要么创建一个子字符串,它是您的smallString 变量的长度,然后比较两者。或者搜索子字符串smallString,看看它是否返回索引0

              【讨论】:

                【解决方案11】:

                http://www.cplusplus.com/reference/string/string/substr/

                您可以使用 string.substr() 从任何位置查看任意数量的字符,也可以使用 string.find() 成员。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2010-09-21
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-06-13
                  • 2018-08-12
                  • 1970-01-01
                  • 2019-08-24
                  相关资源
                  最近更新 更多