Notice
Recent Posts
Recent Comments
Link
«   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
Archives
Today
Total
05-16 20:20
관리 메뉴

nomad-programmer

[Programming/C++] 문자 함수를 위한 cctype 라이브러리 본문

Programming/C++

[Programming/C++] 문자 함수를 위한 cctype 라이브러리

scii 2023. 2. 21. 00:33

cin.get(char)를 이용한 입력

일반적으로 문자 단위로 입력을 읽어들이는 프로그램들은 빈칸 문자, 탭 문자, 개행 문자까지 포함하여 모든 문자를 읽어들여야 한다. cin이 속해 있는 istream 클래스는 이런 요구를 만족시키는 멤버 함수들을 가지고 있다. 특별히 cin.get(ch) 멤버 함수는 빈칸 문자까지도 입력받아 ch 변수에 저장한다. 

#pragma warning(disable: 4996)

#include <iostream>

using namespace std;


int main() {
    char ch;
    int count = 0;

    cin.get(ch);
    while (ch != '#') {
        cout << ch;
        ++count;
        cin.get(ch);
    }

    cout << endl << count << endl;

    return 0;
}


// 결과
did you use a #2 pencil?
14

빈칸 문자를 포함한 모든 문자들을 에코하고 카운트한다. 입력은 여전히 버퍼를 이용하기 때문에, 프로그램이 처리를 끝내는 # 문자 뒤에도 문자를 더 입력할 수 있다.

C에 익숙한 사용자라면 이 프로그램이 무언가 잘못되었다고 생각할 것이다. cin.get(ch) 함수 호출은 ch 변수에 어떤 값을 넣는데, 이것은 그 변수의 값을 변경한다는 것을 뜻한다. C에서는 변수의 값을 변경하려면 그 변수의 주소를 함수에 전달해야 한다. 그런데 &ch가 아닌 ch를 사용하고 있다. 이것은 C에서는 분명 작동하지 않을 것이다. 그러나 C++에서는 함수의 매개변수를 참조형(reference)으로 선언할 경우에 이렇게 사용할 수 있다. 참조형은 C++에 새로운 데이터형이다. iostream 헤더 파일에 cin.get(ch)의 매개변수가 참조형으로 선언되어 있기 때문에, 이 함수는 매개변수의 값을 변경할 수 있다. 


cctype 라이브러리

C++는 문자 관련 함수들의 패기키즐 C언어로부터 물려받았다. 문자 관련 함수들의 원형은 cctype(구식 C++에서는 ctype.h)에 정의되어 있다. 그 함수들은 어떤 문자가 대문자인지, 숫자인지, 구두점 문자인지 등을 판별하는 작업들을 간단하게 처리한다. 예를 들어, isalpha(ch) 함수는 ch가 알파벳 문자이면 0이 아닌 값을 그렇지 않으면 0을 리턴한다. 
그리고 ispunct(ch)는 ch가 콤마나 마침표와 같은 구두점 문자이면 참 값을 리턴한다. 

이 함수들을 사용하는 것이 AND나 OR 연산자를 사용하는 것보다 훨씬 편리하다. 예를 들어 AND와 OR 연산자를 사용하여 ch가 알파벳 문자인지 아닌지 판별하는 코드 단편을 구현하면 다음과 같이 된다.

if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))

isalpha() 함수를 사용하여 이것을 구현하면 다음과 같이 된다.

if (isalpha(ch))

isalpha()가 사용하기 쉬울 뿐만 아니라 더 일반적이다. AND/OR 형식은 A부터 Z까지의 문자 코드가 순서대로 배열되어 있고, 그 범위 안에 다른 문자 코드들이 들어 있지 않다고 가정한다. ASCII 코드에 대해서는 이 가정이 성립한다. 그러나 일반적으로 이 가정이 항상 성립하는 것은 아니다.

다음은 문자를 인식하여 카운트를 세어주는 코드이다.

#pragma warning(disable: 4996)

#include <iostream>
#include <cctype>

using namespace std;


int main() {
    cout << "input text. "
        "eof() -> #\n";

    char ch;

    int whitespace = 0;
    int digits = 0;
    int chars = 0;
    int punct = 0;
    int others = 0;

    cin.get(ch);
    while (ch != '#') {
        if (isalpha(ch))
            chars++;
        else if (isspace(ch))
            whitespace++;
        else if (isdigit(ch))
            digits++;
        else if (ispunct(ch))
            punct++;
        else
            others++;
        cin.get(ch);
    }

    cout << "alpha char: " << chars << endl;
    cout << "space char: " << whitespace << endl;
    cout << "number char: " << digits << endl;
    cout << "punct char: " << punct << endl;
    cout << "other char: " << others << endl;

    return 0;
}


// 결과
input text. eof() -> #
vision international producer new 3-d film, a remake of andre, for 2023. #
alpha char: 52
space char: 12
number char: 5
punct char: 4
other char: 0

다음은 cctype 라이브러리에 들어 있는 문자 관련 함수들을 요약한 것이다. 일부 C++ 시스템에서는 이 중 몇 가지가 부족하거나 많은 경우도 있다.

함수 이름 반환 값
isalnum() 매개변수가 영숫자, 즉 알파벳 문자이거나 숫자이면 true
isalpha() 매개변수가 알파벳 문자이면 true
isblank() 매개변수가 빈칸 문자 또는 수평 탭 문자이면 true
iscntrl() 매개변수가 제어 문자이면 true
isdigit() 매개변수가 십진 숫자이면(0~9) true
isgraph() 매개변수가 빈칸이 아닌 인쇄할 수 있는 문자이면 true
islower() 매개변수가 소문자이면 true
isprint() 매개변수가 빈칸을 포함하여 인쇄할 수 있는 문자이면 true
ispunct() 매개변수가 구두점 문자이면 true
isspace() 매개변수가 표준 화이트스페이스, 즉 빈칸(a space), 용지 이송(formfeed), 개행(newline), 캐리지 리턴(carriage return), 수평 탭(horizontal tab), 수직 탭(vertical tab) 문자이면 true
isupper() 매개변수가 대문자이면 true
isxdigit() 매개변수가 16진수 숫자(0~9, a~f 또는 A~F)이면 true
tolower() 매개변수가 대문자이면 소문자로 바꾸어 리턴한다. 그렇지 않으면 매개변수를 변경하지 않고 그대로 리턴한다.
toupper() 매개변수가 소문자이면 대문자로 바꾸어 리턴한다. 그렇지 않으면 매개변수를 변경하지 않고 그대로 리턴한다.

 

Comments