Що означає фраза std::string::npos
у наступному фрагменті коду?
found = str.find(str2);
if (found != std::string::npos)
std::cout << "first 'needle' found at: " << int(found) << std::endl;
Відповіді:
Це означає, що не знайдено.
Зазвичай його визначають так:
static const size_t npos = -1;
Краще порівнювати з npos замість -1, оскільки код є більш розбірливим.
cout<<"pos: "<<str.find("not in the string")<<" npos: "<<std::string::npos;
і отримую, pos:4294967295 npos: 4294967295
коли запускаю в Windows, але на Mac я отримую pos:4294967295 npos: 18446744073709551615
. Це не здається правильно ... ну будь-яким способом я пропоную порівнювати -1
замістьstd::string::npos
string::npos
це константа (можливо -1
), що представляє непозицію. Він повертається методом, find
коли шаблон не знайдено.
У документі string::npos
сказано:
npos - це постійне значення статичного члена з найбільшим можливим значенням для елемента типу size_t.
Як повернене значення воно зазвичай використовується для позначення відмови.
Ця константа фактично визначається зі значенням -1 (для будь-якої ознаки), яке, оскільки size_t є непідписаним цілісним типом, стає найбільшим можливим представленим значенням для цього типу.
size_t
це беззнаковое змінна, таким чином , «значення без знака = - 1» автоматично робить його максимально можливе значення size_t
: 18446744073709551615
std::string::npos
це індекс, визначений реалізацією, який завжди виходить за межі будь-якого std::string
екземпляра. Різні std::string
функції повертають його або приймають для сигналу після кінця рядкової ситуації. Зазвичай він має якийсь цілий тип без підпису, і його значення зазвичай таке, std::numeric_limits<std::string::size_type>::max ()
яке (завдяки стандартним цілочисельним акціям) зазвичай можна порівняти з -1
.
ми повинні використовувати string::size_type
для типу повернення функції пошуку, інакше порівняння з string::npos
може не спрацювати.
size_type
, який визначається розподільником рядка, повинен бути unsigned
інтегральним типом. Розподільник за замовчуванням, розподільник, використовує тип size_t
як size_type
. Оскільки -1
перетворюється в непідписаний інтегральний тип, npos - це максимальне непідписане значення свого типу. Однак точне значення залежить від точного визначення типу size_type
. На жаль, ці максимальні значення відрізняються. Фактично, (unsigned long)-1
відрізняється від (unsigned short)-
1, якщо розмір типів відрізняється. Таким чином, порівняння
idx == std::string::npos
може дати false, якщо idx має значення -1
та idx і string::npos
має різні типи:
std::string s;
...
int idx = s.find("not found"); // assume it returns npos
if (idx == std::string::npos) { // ERROR: comparison might not work
...
}
Один із способів уникнути цієї помилки - перевірити, чи не вдається безпосередньо пошук:
if (s.find("hi") == std::string::npos) {
...
}
Однак часто вам потрібен індекс відповідного положення символу. Таким чином, іншим простим рішенням є визначення власного підписаного значення для npos:
const int NPOS = -1;
Тепер порівняння виглядає дещо інакше і навіть зручніше:
if (idx == NPOS) { // works almost always
...
}
npos - це просто символічне значення, яке повідомляє, що find () нічого не знайшов (можливо, -1 або щось подібне). find () перевіряє першу появу параметра і повертає індекс, з якого починається параметр. Наприклад,
string name = "asad.txt";
int i = name.find(".txt");
//i holds the value 4 now, that's the index at which ".txt" starts
if (i==string::npos) //if ".txt" was NOT found - in this case it was, so this condition is false
name.append(".txt");
статична const size_t npos = -1;
Максимальне значення для size_t
npos - це постійне значення статичного члена з найбільшим можливим значенням для елемента типу size_t.
Це значення, коли використовується як значення для параметра len (або сублін) у функціях-членах рядка, означає "до кінця рядка".
Як повернене значення воно зазвичай використовується для позначення відсутніх збігів.
Ця константа визначається зі значенням -1, що, оскільки size_t є непідписаним цілісним типом, це найбільше можливе представлене значення для цього типу.
Відповідь на ці дні C ++ 17, коли ми маємо std::optional
:
Якщо ви трохи примружили очі і робили вигляд, що std::string::find()
повертає std::optional<std::string::size_type>
(що як би слід ...) - тоді умова стає:
auto position = str.find(str2);
if ( position.has_value() ) {
std::cout << "first 'needle' found at: " << found.value() << std::endl;
}
Значення string :: npos - 18446744073709551615. Його значення повертається, якщо рядок не знайдено.
18446744073709551615
було б типовим для 64-розрядних std::size_t
, це максимальне 64-розрядне беззнакове значення.