Co oznacza fraza std::string::npos
w poniższym fragmencie kodu?
found = str.find(str2);
if (found != std::string::npos)
std::cout << "first 'needle' found at: " << int(found) << std::endl;
Odpowiedzi:
To znaczy nie znaleziono.
Zazwyczaj definiuje się go następująco:
static const size_t npos = -1;
Lepiej jest porównać npos zamiast -1, ponieważ kod jest bardziej czytelny.
cout<<"pos: "<<str.find("not in the string")<<" npos: "<<std::string::npos;
i otrzymuję, pos:4294967295 npos: 4294967295
gdy uruchamiam to w systemie Windows, ale na Macu dostaję pos:4294967295 npos: 18446744073709551615
. To nie wydaje się słuszne ... cóż, w żaden sposób sugeruję porównanie do -1
zamiaststd::string::npos
string::npos
jest stałą (prawdopodobnie -1
) reprezentującą brak pozycji. Jest zwracany przez metodę, find
gdy wzorzec nie został znaleziony.
Dokument dla string::npos
mówi:
npos to statyczna wartość składowa o największej możliwej wartości dla elementu typu size_t.
Jako wartość zwracana jest zwykle używana do wskazania awarii.
Ta stała jest w rzeczywistości zdefiniowana za pomocą wartości -1 (dla dowolnej cechy), która, ponieważ size_t jest typem całkowitym bez znaku, staje się największą możliwą do reprezentowania wartością dla tego typu.
size_t
jest zmienną bez znaku, więc „wartość bez znaku = - 1” automatycznie czyni ją największą możliwą wartością dla size_t
: 18446744073709551615
std::string::npos
jest indeksem zdefiniowanym przez implementację, który jest zawsze poza zakresem jakichkolwiek std::string
instancji. Różne std::string
funkcje zwracają go lub akceptują, aby zasygnalizować koniec sytuacji ze strunami. Zwykle jest to typ liczby całkowitej bez znaku, a jego wartość jest zwykle std::numeric_limits<std::string::size_type>::max ()
(dzięki standardowym promocjom całkowitoliczbowym) porównywalna z -1
.
musimy użyć string::size_type
dla zwracanego typu funkcji find, w przeciwnym razie porównanie z string::npos
może nie działać.
size_type
, który jest definiowany przez alokator ciągu, musi być unsigned
typem całkowitym. Domyślny alokator, alokator, używa typu size_t
as size_type
. Ponieważ -1
jest konwertowany na typ całkowity bez znaku, npos jest maksymalną wartością bez znaku tego typu. Jednak dokładna wartość zależy od dokładnej definicji typu size_type
. Niestety te wartości maksymalne są różne. W rzeczywistości (unsigned long)-1
różni się od (unsigned short)-
1, jeśli rozmiar typów jest inny. Tak więc porównanie
idx == std::string::npos
może dać false, jeśli idx ma wartość -1
i idx i string::npos
ma różne typy:
std::string s;
...
int idx = s.find("not found"); // assume it returns npos
if (idx == std::string::npos) { // ERROR: comparison might not work
...
}
Jednym ze sposobów uniknięcia tego błędu jest sprawdzenie, czy wyszukiwanie nie powiedzie się bezpośrednio:
if (s.find("hi") == std::string::npos) {
...
}
Jednak często potrzebny jest indeks odpowiadającej pozycji znaku. Dlatego innym prostym rozwiązaniem jest zdefiniowanie własnej wartości ze znakiem dla npos:
const int NPOS = -1;
Teraz porównanie wygląda nieco inaczej i jeszcze wygodniej:
if (idx == NPOS) { // works almost always
...
}
Wartość string :: npos to 18446744073709551615. Jest to wartość zwracana, jeśli nie zostanie znaleziony żaden ciąg.
18446744073709551615
byłaby to jednak wartość typowa dla 64-bitów std::size_t
, jest to maksymalnie 64-bitowa wartość bez znaku.
npos to po prostu wartość symboliczna, która mówi ci, że funkcja find () niczego nie znalazła (prawdopodobnie -1 lub coś w tym rodzaju). Funkcja find () sprawdza pierwsze wystąpienie parametru i zwraca indeks, od którego zaczyna się parametr. Na przykład,
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");
static const size_t npos = -1;
Maksymalna wartość dla size_t
npos to statyczna wartość składowa o największej możliwej wartości dla elementu typu size_t.
Ta wartość, gdy jest używana jako wartość parametru len (lub sublen) w funkcjach składowych łańcucha, oznacza „do końca ciągu”.
Jako wartość zwracana jest zwykle używana do wskazania braku dopasowań.
Ta stała jest definiowana za pomocą wartości -1, która, ponieważ size_t jest typem całkowitym bez znaku, jest to największa możliwa do reprezentacji wartość dla tego typu.
Odpowiedź na te dni C ++ 17, kiedy mamy std::optional
:
Jeśli trochę zmrużysz oczy i udasz, że std::string::find()
zwraca std::optional<std::string::size_type>
(co w pewnym sensie powinno ...) - wtedy warunek będzie wyglądał następująco:
auto position = str.find(str2);
if ( position.has_value() ) {
std::cout << "first 'needle' found at: " << found.value() << std::endl;
}