본문 바로가기

BackEnd/C랑 C++

C++ 대문자/소문자 변환

너무 바빠서 긴 포스팅 글의 마무리를 못하고 있다..

일단 가벼운거라도 올려야 들 억울할 것 같다

 

1. std::transform 사용

2. std::toupper & std::tolower 사용

3. boost::to_upper 와 to_lower 사용

 

 


1. std::transform

구글에 "C++ 대소문자 변환" 이라고 검색하면 

아마 가장 먼저 보이는 라이브러리이지 않을까 싶다

사용 방법을 보기전에 cppreference에 있는 함수 형태를 먼저 보겠다

 

* 헤더

#include <algorithm>

헤더는 요렇고,,

 

* 함수 원형(?)

template< class InputIt, class OutputIt, class UnaryOperation >
OutputIt transform( InputIt first1, InputIt last1, OutputIt d_first,
                    UnaryOperation unary_op );

..? 복잡하게 생겼지만, transform 뜻 자체가 "변환"이지 않은가

Input 을 한 무언가를 원하는 방법에 따라 Output 으로 바꾸겠다 요런 뜻이라고 예상이 된다

원하는 방법이 우리는 대/소문자 변환일테고 ㅋ

 

transform 함수를 좀더 쉬운 모양으로 보자면,

Output transform(
/*1*/ 입력한 변수의 first 위치, 
/*2*/ 입력한 변수의 last 위치까지, 
/*3*/ 저장할 변수의 first 위치, 
/*4*/ 변환할 방법이 있는 함수
); 

이렇게 얘기할 수 있을 것 같당

예를 들어서, "tistory"라는 글자를 대문자로 바꾸고 싶다면?

 

#include <algorithm>
#include <string>

using namespace std;
int main(int argc, char **argv)
{
    string str = "Tistory";
    transform(str.begin(), str.end(), str.begin(), ::toupper);
    
    cout << str << endl; /* Return: TISTORY */
    
    return 0;
}

 

cf) std::toupper & std::tolower

transform 함수 마지막 파라미터의 std::toupper는 std::transfrom() 처럼 std에서 제공하는 라이브러리이다

 

- std::toupper : 대문자로 변환하는 함수

- std::tolower : 소문자로 변환하는 함수

 

작성하려고 보니 toupper와 tolower도 추가해야겠음 (아래 참고)

 

std::에서 제공하는 함수를 사용할 수도 있고, 새로 정의한 함수를 사용할 수도 있다

예를 들어, vector 안에 있는 요소에 1씩 더하려면, 1씩 더하는 함수를 만들어서 파라미터로 넘겨주면 된다

 

* 예시

#include <algorithm>
#include <string>

using namespace std;

int plusFunc(int num)
{
    return num + 1;
}

void printVec(vector<int> vec)
{
    for( int i=0; i < (int)vec.size(); i++)
        cout << i << ": "<< vec[i] << endl;
    return;
}

int main(int argc, char **argv)
{
    vector<int> input {1, 2, 3};
    vector<int> output(3);

    printVec(input); 
    transform(input.begin(), input.end(), output.begin(), plusFunc);
    printVec(output);

    return 0;
}

 

* iterator 사용

transform()을 조금만 구글링하면 나오는 예시는 보통 string/vector 일 것이다

Iterator를 가지는 input과 output을 사용해야한다는 것을 기억해두자

 

2. std::toupper & std::tolower 사용

(1) std::toupper 

 

문득 transform()에 toupper()를 사용하다가 든 생각이,

toupper()는 잘 몰라서 엥 그냥 바로 toupper를 쓰면 되는거 아닌가? 라는 생각이 들었다

이유는 → 한 글자만 바꿀 수 있기 때문 ㅋ 그래서 문자열을 바꾸고 싶다면

transform이랑 써야하는거였음 ㅋ 아 ㅋ

 

* 함수 원형

#include <cctype>
int toupper ( int ch ) ;

- parameter: 보통 unsigned char 타입의 문자열을 많이 씁니다

- return value: 대문자로 바뀐 결과 값

 

* 예시

using namespace std;
int main(int argc, char **argv)
{
	unsigned char c = 't';
	auto ret = std::toupper(c);
    cout << static_cast<char>(ret) << endl; /* Return: T */
    
    return 0;
}

 

(2) std::tolower

toupper와 반대로 소문자로 변환해준다

설명은 패쓰하고 함수 원형만 예시만 다루겠다

 

* 함수 원형

#include <cctype>
int tolower( int ch )

* 예시

using namespace std;
int main(int argc, char **argv)
{
	unsigned char c = 'B';
	auto ret = std::toupper(c);
    cout << static_cast<char>(ret) << endl; /* Return: b */
    
    return 0;
}

 

3. boost::to_upper 와 to_lower 사용 (+ boost::to_upper_copy)

boost에서도 std::transform + std::toupper 같은 기능을 제공하는 함수가 있다

나는 부스트를 좋아하니까,, 앞으로 이걸 많이 쓰려고 한다

 

* 함수 원형

#include <boost/algorithm/string.hpp>

template<typename WritableRangeT> 
  void to_upper(WritableRangeT & Input, 
                const std::locale & Loc = std::locale());

 

내가 boost::to_upper를 선호하는 이유는 파라미터 때문이다

예시로 바로 설명하자면,

 

* ㅇㅅ

int
main(int argc, char **argv)
{
    string str = "tistory_mutpp";
    string str2 = "tistory_mutpp";
    string str3 = "tistory_mutpp";
    string ret;

    transform(str.begin(), str.end(), str.begin(), (int(*)(int))toupper);
    cout << str << endl; /* Return: TISTORY_MUTPP */

    transform(str2.begin(), str2.end(), str2.begin(), ::toupper);
    cout << str2 << endl; /* Return: TISTORY_MUTPP */

    boost::to_upper(str3);
    cout << str3 << endl; /* Return: TISTORY_MUTPP */
    
    return 0;
}

 

boost::to_upper(바꿀 문자열);

 

바꾸고 싶은 문자열을 넣기만 하면 되는거다 ㅋ

근데 바꿀 문자열을 같은 변수에 바꿔서 저장하기 때문에 원형이 바뀐다

(return type 또한 void)

 

친절한 부스트씨는 그래서 결과를 복사해서 주는 함수도 제공해준다 → boost::to_upper_copy

 

* boost::to_upper_copy

template<typename OutputIteratorT, typename RangeT> 
  OutputIteratorT 
  to_upper_copy(OutputIteratorT Output, const RangeT & Input, 
                const std::locale & Loc = std::locale());
template<typename SequenceT> 
  SequenceT to_upper_copy(const SequenceT & Input, 
                          const std::locale & Loc = std::locale());
부스트씨: Each element of the input sequence is converted to upper case. The result is a copy of the input converted to upper case. It is returned as a sequence or copied to the output iterator

예시만 들어서 설명을 끝내겠다

int
main(int argc, char **argv)
{
    string str = "tistory_mutpp";
    
    cout << str << endl; /* Return: tistory_mutpp */
    
    string ret = boost::to_upper_copy(str);
    
    cout << str << endl; /* Return: tistory_mutpp */
    cout << ret << endl; /* Return: TISTORY_MUTPP */
    
    return 0;
}

 


* cppreference

en.cppreference.com/w/cpp/algorithm/transform

 

std::transform - cppreference.com

(1) template< class InputIt, class OutputIt, class UnaryOperation > OutputIt transform( InputIt first1, InputIt last1, OutputIt d_first,                     UnaryOperation unary_op ); (until C++20) template< class InputIt, class OutputIt, class U

en.cppreference.com

* boost 

www.boost.org/doc/libs/1_41_0/doc/html/boost/algorithm/to_upper.html

 

Function template to_upper - 1.41.0

Function template to_upper boost::algorithm::to_upper — Convert to upper case. Synopsis // In header: template void to_upper(WritableRangeT & Input, const std::locale & Loc = std::locale()); Description Each element of the input sequence is converted to

www.boost.org

* boost to_upper_copy

www.boost.org/doc/libs/1_54_0/doc/html/boost/algorithm/to_upper_copy.html

 

Function to_upper_copy - 1.54.0

Function to_upper_copy boost::algorithm::to_upper_copy — Convert to upper case. Synopsis template OutputIteratorT to_upper_copy(OutputIteratorT Output, const RangeT & Input, const std::locale & Loc = std::locale()); template SequenceT to_upper_copy(const

www.boost.org