std::string::find
표준 C ++ 컨테이너와 동작 이 일치하지 않습니다.
예 :
std::map<int, int> myMap = {{1, 2}};
auto it = myMap.find(10); // it == myMap.end()
그러나 문자열의 경우
std::string myStr = "hello";
auto it = myStr.find('!'); // it == std::string::npos
왜 실패한 myStr.find('!')
반품 myStr.end()
이 std::string::npos
아닌가?
std::string
다른 컨테이너와 비교할 때 다소 특별 하기 때문에 이것 뒤에 진짜 이유가 있는지 궁금합니다. (놀랍게도, 나는 이것을 어디에서나 질문하는 사람을 찾을 수 없었다).
답변
우선, std::string
인터페이스가 부풀어지고 일관성이없는 것으로 잘 알려져 있습니다 .이 주제에 대한 Herb Sutter의 Gotw84 를 참조하십시오 . 그럼에도 불구하고 std::string::find
인덱스를 반환하는 이유는 다음과 같습니다 std::string::substr
. 이 편리한 멤버 함수는 인덱스에서 작동합니다. 예 :
const std::string src = "abcdefghijk";
std::cout << src.substr(2, 5) << "\n";
substr
반복자를 문자열로 받아들이도록 구현할 수는 있지만 std::string
사용할 수없고 반 직관적 인 큰 불만을 기다릴 필요 는 없습니다. 따라서 std::string::substr
인덱스 를 받아들이면 'd'
이 하위 문자열에서 시작하는 모든 것을 인쇄하기 위해 위의 입력 문자열에서 처음 나타나는 인덱스를 어떻게 찾을 수 있습니까?
const auto it = src.find('d'); // imagine this returns an iterator
std::cout << src.substr(std::distance(src.cbegin(), it));
이것은 또한 당신이 원하는 것이 아닐 수도 있습니다. 따라서 우리 std::string::find
는 색인을 반환하도록 할 수 있으며 여기에 있습니다 :
const std::string extracted = src.substr(src.find('d'));
이터레이터로 작업하려면을 사용하십시오 <algorithm>
. 그들은 당신을 위와 같이 허용합니다
auto it = std::find(src.cbegin(), src.cend(), 'd');
std::copy(it, src.cend(), std::ostream_iterator<char>(std::cout));
답변
std::string
두 가지 인터페이스 가 있기 때문입니다 .
- 모든 컨테이너에서 발견 되는 일반 반복자 기반 인터페이스
std::string
특정의 인덱스 기반의 인터페이스
std::string::find
인덱스 기반 인터페이스의 일부 이므로 인덱스를 반환합니다.
사용하여 std::find
일반 반복자 기반 인터페이스를 사용 할 수 있습니다.
std::vector<char>
인덱스 기반 인터페이스를 원하지 않는 경우 사용하십시오 (이 작업을 수행하지 마십시오).