Co oznacza string :: npos w tym kodzie?

95

Co oznacza fraza std::string::nposw poniższym fragmencie kodu?

found = str.find(str2);

if (found != std::string::npos)
    std::cout << "first 'needle' found at: " << int(found) << std::endl;
Bum
źródło

Odpowiedzi:

109

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.

Brian R. Bondy
źródło
3
Porównanie == -1 może sprawić, że niektórzy ludzie pomyślą, że mogą przekształcić to w <0, co NIE jest tym samym i nie będzie działać.
Andy Dent
Zastanawiam się tylko, czy ktoś się z tym spotkał, czy to tylko ja ... Uruchamiam cout<<"pos: "<<str.find("not in the string")<<" npos: "<<std::string::npos;i otrzymuję, pos:4294967295 npos: 4294967295gdy 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 -1zamiaststd::string::npos
user1135469
@ user1135469, jeśli zobaczysz odpowiedź codaddict poniżej ( stackoverflow.com/a/3827997/752842 ) lub Sebastiana Raschki, myślę, że to, co otrzymujesz, będzie miało sens. I polecałbym używanie npos, ponieważ próbowałem użyć -1 i nie działało poprawnie w warunkach, w których go używałem.
Dzyann
50

string::nposjest stałą (prawdopodobnie -1) reprezentującą brak pozycji. Jest zwracany przez metodę, findgdy wzorzec nie został znaleziony.

Sheldon L. Cooper
źródło
15
+1 za faktyczne pokazanie wyprowadzenia npos = no-pos, które ułatwia zapamiętanie. To takie oczywiste, że nie pomyślałbyś o tym, gdybyś to wiedział, ale dla kogoś, kto widzi te litery po raz pierwszy, może nie kliknąć ...?
Tony Delroy,
4
źle na 47 poziomach ... npos ma size_t, oznacza to, że nie może być ujemne ... prawdziwe znaczenie to max_index, 18446744073709551615 dla 64 bit size_t
NoSenseEtAl
25

Dokument dla string::nposmó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.

codaddict
źródło
17

size_tjest zmienną bez znaku, więc „wartość bez znaku = - 1” automatycznie czyni ją największą możliwą wartością dla size_t: 18446744073709551615


źródło
size_t jest unsigned int dla kompilatora 32-bitowego; unsigned long long int dla kompilatora 64-bitowego. Ustawienie wartości -1 powoduje, że ma on maksymalną wartość tego typu bez znaku.
sudheerbb
9

std::string::npos jest indeksem zdefiniowanym przez implementację, który jest zawsze poza zakresem jakichkolwiek std::string instancji. Różne std::stringfunkcje 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.

wilx
źródło
4

musimy użyć string::size_typedla zwracanego typu funkcji find, w przeciwnym razie porównanie z string::nposmoż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_tas size_type. Ponieważ -1jest 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)-1róż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ść -1i idx i string::nposma 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
...
}
Debashish
źródło
3

foundbędzie nposw przypadku niepowodzenia znalezienia podciągu w ciągu wyszukiwania.

Raghuram
źródło
1
$21.4 - "static const size_type npos = -1;"

Jest zwracany przez funkcje tekstowe wskazujące błąd / nie znaleziono itp.

Chubsdad
źródło
1

Wartość string :: npos to 18446744073709551615. Jest to wartość zwracana, jeśli nie zostanie znaleziony żaden ciąg.

Ayush ShaZz
źródło
Rzeczywista wartość jest zdefiniowana w ramach implementacji i nie ma znaczenia. W praktyce 18446744073709551615byłaby to jednak wartość typowa dla 64-bitów std::size_t, jest to maksymalnie 64-bitowa wartość bez znaku.
Alex Guteniev
0

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");
asad_nitp
źródło
Ten kod nie zostanie znaleziony dla „asad.other”, ponieważ funkcja find () nie zwraca int.
LogicMagic
0

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.

Leninkumar
źródło
0

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;
}
einpoklum
źródło