STL의 std::string::find_last_of 사용 시 주의 사항
반응형
출처 : http://alones.kr/blog/627
//
요즘 블로깅을 통 못했다. 1주일 정도.. 바쁘다는 핑계로 너무 게을러 진 것 같아서...
다시 매진해 본다.
STL의 find_last_of를 착각하고 쓴 적이 있어서 이에 대해서 써보았다.
in my wiki: http://alones.byus.net/moniwiki/wiki.php/find_last_of?action=show
- initial version: 2007.05.22
[edit]
1 결론 #
결론 부터 이야기 하면 STL의 std::string::find_last_of는 strtok와 유사하게 인자로 받는 const char* 또는 const std::string& 문자열 내의 각 char에 대한 find_last_of이다. (※ 물론, strtok는 각 char로 tokenizing을 하겠지만)
문자열 전체와 정확히 일치하는 마지막 위치를 찾아 주는 것이 아니고 해당 문자열의 각 char들이 마지막으로 출현하는 index를 반환하는 것이다.
-_-;; 이 걸로 오해하고 쓰다 낭패를 당한적이 있어서... (<== 바보) rfind()를 사용해야 할 것이다.
-_-;; 이 걸로 오해하고 쓰다 낭패를 당한적이 있어서... (<== 바보) rfind()를 사용해야 할 것이다.
[edit]
2 find_last_of의 가능한 착각 #
확장자를 검사하는 코드를 아래와 같이 find_last_of로 작성했다면 불쌍해질 것이다.
std::string str = "test_data.da"; // "dat" 확장자를 가지는 지 bool bDatafile = false; int nIndex = -1; // ".dat"의 위치를 찾자. // [wrong] find_last_of는 주어진 문자열 내의 // 각 char가 match되는 마지막 index를 return // 하기 때문에 str에 대해서 true if( (nIndex = str.find_last_of(".dat")) >= 0 ) { //.dat로 끝나내?? bDatafile = true; } else { //.dat로 끝나는 애가 아니네.. bDatafile = false; }
//
위 코드는 str이 "test_data.da"인 경우도 true를 return할 것이다. str에서 ".dat"의 4글자 중 a가 마지막으로 출현한 index가 11이기 때문이다.
[edit]
3 마지막 matching 되는 str의 index를 찾는 경우는 rfind()를 #
위와 같은 경우는 std::string::find_last_of()가 아닌 std::string::rfind()로 아래와 같이 작성해야 할 것이다.
std::string str = "test_data.da"; // "dat" 확장자를 가지는 지 bool bDatafile = false; int nIndex = -1; // ".dat"의 위치를 찾자. if( (nIndex = str.rfind(".dat") ) >= 0) { //.dat로 끝나내?? bDatafile = true; } else { //.dat로 끝나내느 애가 아니네.. bDatafile = false; }
//
[edit]
4 또 하나의 가능한 실수 size_t #
size_t가 unsigned int 라는 것을 잘 알 것이다. 하지만 이 것을 간과하고 위의 rfind()로 작성한 코드를 아래와 같이 작성한다면 -_-;;
rfind()가 찾지못한 결과에 대한 -1 (i.e. std::string::npos)가 unsigned int로 표현되어 항상 true가 될 것이다.
std::string str = "test_data.da"; // "dat" 확장자를 가지는 지 bool bDatafile = false; int nIndex = -1; // ".dat"의 위치를 찾자. // wrong rfind()는 size_t 즉 unsigned int // 를 return하기 때문에 항상 true if( str.rfind(".dat") ) { //.dat로 끝나내?? bDatafile = true; } else { //.dat로 끝나내느 애가 아니네.. bDatafile = false; } //
위의 경우는 아래 코드와 같이 std::string::npos를 사용하든지 int로 casting을 해서 사용해야 할 것이다.
std::string str = "test_data.da"; // "dat" 확장자를 가지는 지 bool bDatafile = false; int nIndex = -1; // ".dat"의 위치를 찾자. // size_t반환이고 -1은 std::string::npos if( str.rfind(".dat") != std::string::npos) { //.dat로 끝나내?? bDatafile = true; } else { //.dat로 끝나내느 애가 아니네.. bDatafile = false; }
'Study > C++' 카테고리의 다른 글
compile time assertion (0) | 2010.06.10 |
---|---|
FileChecker (0) | 2010.06.09 |
__int8, __int16, __int32, __int64 (0) | 2010.05.30 |
volatile (0) | 2010.05.29 |
mec++에 있는 auto_ptr (0) | 2010.05.28 |
TAGS.