티스토리 뷰
[Modern C++, string, tolower] 문자열내 문자 소문자 변환 방법, 근데 이제 파이썬의 .lower() 같은 한줄 코드의 느낌을 곁들인
developer0hye 2023. 1. 19. 21:46여기서 소문자/대문자는 영어에만 국한함
다른 문자는 안다뤄봐서 잘 모른다.
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
https://cplusplus.com/reference/locale/tolower/
그래서 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/313970/how-to-convert-an-instance-of-stdstring-to-lower-case
https://en.cppreference.com/w/cpp/string/byte/tolower
끝맺음
되게 별거 아닌거같은데 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
'C++' 카테고리의 다른 글
[C++] C++ std::array<> too many initializers (0) | 2023.01.30 |
---|---|
[C++] 컴파일러별 C++ 버전별 지원 기능 확인 (0) | 2023.01.23 |
[C++] sizeof 는 알겠는데, sizeof... 는 뭐지? (0) | 2023.01.15 |
[Modern C++] for_each, 반복자 cin/cout 입출력 응용 (0) | 2023.01.15 |
[Modern C++] vector argmin, argmax (2) | 2023.01.06 |
- Total
- Today
- Yesterday
- PyCharm
- 파이참
- 백준
- 백준 11437
- 백트래킹
- MOT
- 문제집
- Lowest Common Ancestor
- 위상 정렬 알고리즘
- 순열
- ㅂ
- C++ Deploy
- cosine
- 자료구조
- 백준 1766
- 조합
- LCA
- 가장 긴 증가하는 부분 수열
- FairMOT
- 단축키
- 백준 11053
- 인공지능을 위한 선형대수
- 이분탐색
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |