티스토리 뷰

여기서 소문자/대문자는 영어에만 국한함

 

다른 문자는 안다뤄봐서 잘 모른다.

 

boost 안다룬다.

 

속도 안재봤다.

 

C++17 로 테스트했다.

1. for_each 활용

#include <iostream>
#include <algorithm>
#include <string>

int main()
{
    std::string str = "DevEloPer0Hye";
    std::cout << str << " -> ";
    std::for_each(str.begin(), str.end(), [](auto& c){c = tolower(c);});
    std::cout << str;
    
    return 0;
}

출력

DevEloPer0Hye -> developer0hye

 

2. transform 활용

#include <iostream>
#include <algorithm>
#include <string>

int main()
{
    std::string str = "DevEloPer0Hye";
    std::cout << str << " -> ";
    std::transform(str.begin(), str.end(), str.begin(), tolower);
    std::cout << str;
    
    return 0;
}

출력

DevEloPer0Hye -> developer0hye

 

주의할 점

 

std::tolower 구현이 두개가 있다.

 

UnaryOperation 으로 돼있는 것도 있고 아닌것도있다.

 

https://en.cppreference.com/w/cpp/string/byte/tolower

 

std::tolower - cppreference.com

Converts the given character to lowercase according to the character conversion rules defined by the currently installed C locale. In the default "C" locale, the following uppercase letters ABCDEFGHIJKLMNOPQRSTUVWXYZ are replaced with respective lowercase

en.cppreference.com

 

https://cplusplus.com/reference/locale/tolower/

 

https://cplusplus.com/reference/locale/tolower/

function template <locale> std::tolower template charT tolower (charT c, const locale& loc); Convert uppercase letter to lowercase using locale Converts parameter c to its lowercase equivalent if c is an uppercase letter and has a lowercase equivalent, as

cplusplus.com

 

그래서 std::transform(..., tolower) 대신에  std::transform(..., std::tolower) 하면 알아서 UnaryOperation 함수인 tolower로 인식하지 못해서 컴파일 오류가 발생한다.

 

또 using namespace std; 해놓고

 

std::transform(..., tolower) 해버리면 마찬가지로 어떤 tolower인지 모르기에 컴파일 오류가 발생한다. 

 

 

cppreference에도 std::transform 을 써서 구현한게 있다. 이렇게 하면 기존에  using namespace std; 를 해놓고 코드를 구현한 경우에도 컴파일 오류안나고 transform 과 tolower를 함께 써서 코딩할 수 있다.

위처럼 구현하면 코드는 좀 길어진다.

 

다시 1. for_each 버전보고 이 코드 봐보자. 체력이 많은 경우 아래 코드를 참고하고, 체력이 적은 경우 1. for_each 버전으로 쓰자. 혹은 using namespace std;와 작별을 고하고 2. transform 버전을 쓰자.

#include <iostream>
#include <algorithm>
#include <string>

int main()
{
    std::string str = "DevEloPer0Hye";
    std::cout << str << " -> ";
    std::transform(str.begin(), str.end(), str.begin(), [](auto c){return std::tolower(c);});
    std::cout << str;
    
    return 0;
}

출력

DevEloPer0Hye -> developer0hye

 

참고

https://stackoverflow.com/questions/5539249/why-cant-transforms-begin-s-end-s-begin-tolower-be-complied-successfu/5539423#5539423

 

Why can't "transform(s.begin(),s.end(),s.begin(),tolower)" be complied successfully?

Given the code: #include <iostream> #include <cctype> #include <string> #include <algorithm> using namespace std; int main() { string s("ABCDEFGHIJKL"); transfor...

stackoverflow.com

 

 

https://stackoverflow.com/questions/313970/how-to-convert-an-instance-of-stdstring-to-lower-case

 

How to convert an instance of std::string to lower case

I want to convert a std::string to lowercase. I am aware of the function tolower(). However, in the past I have had issues with this function and it is hardly ideal anyway as using it with a std::s...

stackoverflow.com

https://en.cppreference.com/w/cpp/string/byte/tolower

 

std::tolower - cppreference.com

Converts the given character to lowercase according to the character conversion rules defined by the currently installed C locale. In the default "C" locale, the following uppercase letters ABCDEFGHIJKLMNOPQRSTUVWXYZ are replaced with respective lowercase

en.cppreference.com

 

끝맺음

되게 별거 아닌거같은데 modern c++을 잘 활용하면 보다 간결하고 안전한 코드를 짤 수 있을 거 같다.

 

위 코드보고 안전한 코드라고 바로 떠올리기는 어려운데 내가 생각하는 안전한이란

 

for(int i=0; i<str.size(); i++) 이런식으로 기존에는 반복문을 돌며 접근해야했다면, i=0 으로 초기화도 잘해줘야하고 i <=str.size() 이렇게 부등호를 잘못쓰면 안되고, i++도 뭐 i--식으로 잘못쓰면 안되는데 for_each나 transform을 쓰면 begin, end만 딱 잘 정해주면 된다. 뭐 Ranged-based for loop 를 사용해 for(auto& c: str) 이런식으로도 돌수야 있지만...

 

한 라인에 적어야할 코드가 훨씬 줄어들지만... 이건 개인적으로 뭔가 좀 설명하기 그런데 좀 그렇다.

#include <iostream>
#include <algorithm>
#include <string>

int main()
{
    std::string str = "DevEloPer0Hye";
    std::cout << str << " -> ";
    for(auto& c:str) c = tolower(c);
    std::cout << str;
    return 0;
}

출력

DevEloPer0Hye -> developer0hye

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함