Есть ли способ в С++ проверить, начинается ли строка с определенной строки (меньше оригинала)? Так же, как мы можем сделать в Java
bigString.startswith(smallString);
Есть ли способ в С++ проверить, начинается ли строка с определенной строки (меньше оригинала)? Так же, как мы можем сделать в Java
bigString.startswith(smallString);
std::string s("Hello world");
if (s.find("Hello") == 0)
{
std::cout << "String starts with Hello\n";
}
Вы можете сделать это с помощью string::compare()
, который предлагает различные варианты для сравнения всех или частей двух строк. Эта версия сравнивает smallString
с соответствующим префиксом размера bigString
(и работает корректно, если bigString
короче smallString
):
bigString.compare(0, smallString.length(), smallString)
Я склонен обернуть это в бесплатную функцию под названием startsWith()
, так как в противном случае она может выглядеть немного загадочной.
UPDATE: С++ 20 добавляет новые функции starts_with
и ends_with
, поэтому вы, наконец, сможете писать просто bigString.starts_with(smallString)
.
Подходы, использующие 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());
}
Правильное решение, как всегда, происходит от Boost: boost::algorithm::starts_with
.
Чтобы немного оптимизировать:
if ( smallString.size() <= bigString.size() &&
strncmp( smallString.c_str(), bigString.c_str(), smallString.length() ) == 0 )
dont forget to #include <cstring> // or <string.h>
Самый простой способ:
if ( smallString.size() <= bigString.size()
&& std::equals( smallString.begin(), smallString.end(), bigString.end() )
(Это также будет работать, если один из двух или обоих векторов. другой стандартный тип контейнера.)
strstr()
возвращает указатель на первое вхождение строки внутри строки.
Я подумал, что имеет смысл опубликовать необработанное решение, которое не использует никаких библиотечных функций...
// 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;
}
Я удивлен, что никто еще не опубликовал этот метод:
#include <string>
using namespace std;
bool starts_with(const string& smaller_string, const string& bigger_string)
{
return (smaller_string == bigger_string.substr(0,smaller_string.length()));
}
Создайте подстроку, которая является длиной вашей переменной smallString
, и сравните их. Или выполните поиск подстроки smallString
и посмотрите, возвращает ли он индекс 0
http://www.cplusplus.com/reference/string/string/substr/
Вы можете использовать string.substr(), чтобы увидеть любое количество символов из любой позиции, или вы можете использовать член string.find().