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

목차

1 결론
2 find_last_of의 가능한 착각
3 마지막 matching 되는 str의 index를 찾는 경우는 rfind()를
4 또 하나의 가능한 실수 size_t
5 Reference


1 결론 #


결론 부터 이야기 하면 STL의 std::string::find_last_of는 strtok와 유사하게 인자로 받는 const char* 또는 const std::string& 문자열 내의 각 char에 대한 find_last_of이다. (※ 물론, strtok는 각 char로 tokenizing을 하겠지만)

문자열 전체와 정확히 일치하는 마지막 위치를 찾아 주는 것이 아니고 해당 문자열의 각 char들이 마지막으로 출현하는 index를 반환하는 것이다.
-_-;; 이 걸로 오해하고 쓰다 낭패를 당한적이 있어서... (<== 바보) rfind()를 사용해야 할 것이다.

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이기 때문이다.

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;
        }

//


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.

Comments