Chuỗi :: npos có nghĩa là gì trong mã này?


91

Cụm từ std::string::npostrong đoạn mã sau có nghĩa là gì?

found = str.find(str2);

if (found != std::string::npos)
    std::cout << "first 'needle' found at: " << int(found) << std::endl;

Câu trả lời:


106

Nó có nghĩa là không tìm thấy.

Nó thường được định nghĩa như vậy:

static const size_t npos = -1;

Tốt hơn là so sánh với npos thay vì -1 vì mã dễ đọc hơn.


3
So sánh == -1 cũng có thể khiến một số người nghĩ rằng họ có thể chuyển đổi giá trị đó thành <0, điều này KHÔNG giống nhau và sẽ không hoạt động.
Andy Dent,

Tôi chỉ tự hỏi nếu có ai đã gặp phải điều này, hoặc chỉ có tôi ... Tôi chạy cout<<"pos: "<<str.find("not in the string")<<" npos: "<<std::string::npos;và nhận được pos:4294967295 npos: 4294967295khi tôi chạy nó trong Windows nhưng trên Mac thì tôi nhận được pos:4294967295 npos: 18446744073709551615. Đó dường như không đúng ... cũng bất cứ cách nào tôi khuyên bạn nên so sánh để -1thay vìstd::string::npos
user1135469

@ user1135469 nếu bạn thấy câu trả lời của codaddict dưới đây ( stackoverflow.com/a/3827997/752842 ) hoặc của Sebastian Raschka, tôi nghĩ những gì bạn nhận được sẽ có ý nghĩa. Và tôi khuyên bạn nên sử dụng npos, bởi vì tôi đã thử sử dụng -1 và nó không hoạt động bình thường trong các điều kiện tôi đang sử dụng.
Dzyann

51

string::nposlà một hằng số (có thể -1) đại diện cho một vị trí không phải. Nó được trả về theo phương thức findkhi không tìm thấy mẫu.


15
+1 để thực sự hiển thị dẫn xuất npos = no-pos giúp bạn dễ nhớ. Rõ ràng là bạn sẽ không nghĩ về nó một khi bạn biết nó, nhưng đối với một người nào đó nhìn thấy những chữ cái đó lần đầu tiên thì có thể không nhấp vào ...?
Tony Delroy

4
sai trên 47 độ ... NPO là size_t, nó có nghĩa là nó không thể là tiêu cực ... ý nghĩa thực sự là max_index, 18446744073709551615 cho 64 bit size_t
NoSenseEtAl

25

Tài liệu cho string::nposbiết:

npos là một hằng số thành viên tĩnh có giá trị lớn nhất có thể cho một phần tử kiểu size_t.

Là một giá trị trả về, nó thường được sử dụng để chỉ ra sự thất bại.

Hằng số này thực sự được xác định với giá trị -1 (đối với bất kỳ đặc điểm nào), vì size_t là kiểu tích phân không dấu, trở thành giá trị có thể biểu diễn lớn nhất cho kiểu này.


17

size_tlà một biến không dấu, do đó, 'giá trị không dấu = - 1' tự động làm cho nó trở thành giá trị lớn nhất có thể cho size_t: 18446744073709551615


size_t là unsigned int cho trình biên dịch 32 bit; unsigned long long int cho trình biên dịch 64 bit .. Đặt nó thành -1 làm cho nó có giá trị tối đa của kiểu unsigned đó.
sudheerbb

9

std::string::nposlà chỉ mục được xác định thực thi luôn nằm ngoài giới hạn của bất kỳ std::stringtrường hợp nào . Các std::stringhàm khác nhau trả về hoặc chấp nhận nó để báo hiệu vượt quá sự kết thúc của tình huống chuỗi. Nó thường thuộc một số kiểu số nguyên không dấu và giá trị của nó thường std::numeric_limits<std::string::size_type>::max ()là (nhờ vào các khuyến mãi số nguyên chuẩn) thường được so sánh với -1.


4

chúng ta phải sử dụng string::size_typecho kiểu trả về của hàm find nếu không so sánh với string::nposcó thể không hoạt động. size_type, được xác định bởi bộ cấp phát của chuỗi, phải là một unsigned kiểu tích phân. Bộ cấp phát mặc định, bộ cấp phát, sử dụng loại size_tsize_type. Vì -1được chuyển đổi thành kiểu tích phân không dấu, npos là giá trị không dấu lớn nhất của kiểu nó. Tuy nhiên, giá trị chính xác phụ thuộc vào định nghĩa chính xác của loại size_type. Thật không may, các giá trị tối đa này khác nhau. Trên thực tế, (unsigned long)-1khác với (unsigned short)-1 nếu kích thước của các loại khác nhau. Như vậy, so sánh

idx == std::string::npos

có thể mang lại false nếu idx có giá trị -1và idx và string::nposcó các loại khác nhau:

std::string s;
...
int idx = s.find("not found"); // assume it returns npos
if (idx == std::string::npos) { // ERROR: comparison might not work
...
}

Một cách để tránh lỗi này là kiểm tra xem tìm kiếm có thất bại trực tiếp hay không:

if (s.find("hi") == std::string::npos) {
...
}

Tuy nhiên, thường bạn cần chỉ số của vị trí ký tự phù hợp. Do đó, một giải pháp đơn giản khác là xác định giá trị có dấu của riêng bạn cho npos:

const int NPOS = -1;

Bây giờ so sánh trông hơi khác một chút và thậm chí còn thuận tiện hơn:

if (idx == NPOS) { // works almost always
...
}

3

foundsẽ đề phòng npostrường hợp không tìm thấy chuỗi con trong chuỗi tìm kiếm.


1
$21.4 - "static const size_type npos = -1;"

Nó được trả về bởi các hàm chuỗi chỉ ra lỗi / không tìm thấy, v.v.


0

npos chỉ là một giá trị mã thông báo cho bạn biết rằng find () không tìm thấy gì (có thể là -1 hoặc tương tự như vậy). find () kiểm tra lần xuất hiện đầu tiên của tham số và trả về chỉ mục mà tại đó tham số bắt đầu. Ví dụ,

  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");

Mã này sẽ không phù hợp với "asad.other" vì find () không trả về int.
LogicMagic

0

static const size_t npos = -1;

Giá trị tối đa cho size_t

npos là một hằng số thành viên tĩnh có giá trị lớn nhất có thể cho một phần tử kiểu size_t.

Giá trị này, khi được sử dụng làm giá trị cho tham số len (hoặc sublen) trong các hàm thành viên của chuỗi, có nghĩa là "cho đến cuối chuỗi".

Là một giá trị trả về, nó thường được sử dụng để biểu thị không có kết quả phù hợp nào.

Hằng số này được xác định với giá trị -1, vì size_t là kiểu tích phân không dấu, nên nó là giá trị có thể biểu diễn lớn nhất cho kiểu này.


0

Câu trả lời cho những ngày này của C ++ 17, khi chúng ta có std::optional :

Nếu bạn nheo mắt một chút và giả vờ std::string::find()trả về một std::optional<std::string::size_type>(mà nó giống như ...) - thì điều kiện sẽ trở thành:

auto position = str.find(str2);

if ( position.has_value() ) {
    std::cout << "first 'needle' found at: " << found.value() << std::endl;
}

0

Giá trị của chuỗi :: npos là 18446744073709551615. Giá trị của nó được trả về nếu không tìm thấy chuỗi nào.


Giá trị thực tế là việc triển khai được xác định và không liên quan. Tuy nhiên, trong thực tế, giá trị 18446744073709551615sẽ là điển hình cho 64-bit std::size_t, đó là giá trị không dấu tối đa 64-bit.
Alex Guteniev
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.