본문 바로가기

C++/FOCU_C++

C++ chpt2.

입력(Input)

 

ex) 배열 생성 후 해당 배열에 데이터 입력

 

char firstName[20];
cin >> firstName;

 

>> 연산자 extraction oprator (string 이 길 때는 공백을 기준으로 나눠서 읽어감)

 

정수형 읽기

int hours;
cin >> hours;
cout << "Today I studied for " << hour << " hores." << endl;

 

부동 소수점형 읽기

 

float price;
cin >> price;
cout << "The price of this green tea is $" << price << "." << endl;

C 의 scanf 와의 비교

 

공통 문제점

'경계검사를 하지 않음'

- 주소 접근으로 인해 '\0' 가 없인 길이 제어가 안됨

- 매번 다른 string 마다 '\0' 로 추가 설정해줘야 됨

 

C 에서 해당 문제 해결 예시

char line[512];
char temp[512];
char firstName[4];

if (fgets(line, 512, stdin) != NULL) // fgets 에다 담을 수 있는 최대 길이를 명시해주고, fgets 가 '\0' 문자를 추가해줌
{
    if (sscanf(line, "%s", temp) == 1 && strlen(temp) < 4) // %s 지정자를 사용함으로써 해당 데이터를 string 으로 읽어오게 설정, sscanf 또한 자동으로 '\0' 를 추가해줌
    {
        strcpy(firstName, temp);
    }
}

 

 

C++ 에서 해당 문제 해결 예시

char firstName[4];
cin >> setw(4) >> firstName; // setw 를 통해 '\0'를 포함한 문자 길이를 설정하면 '\0' 를 자동 추가해줌

 

조금 더 비교하자면 다음과 같다

 

char line[512];
char firstData[512];
int secondData;

// 입력 예시 문구 : "       Hello         123"

if (fgets(line, 512, stdin) != NULL)
{
    sscanf(line, "%s%d", firstData, &secondData);
}

------------------------------------------------------

char firstData[512];
int secondData;

cin >> firstData >> secondData;

_____________________________________________________

firstData = Hello;
secondData = 123;
// white space 는 자동으로 pass

 


스트림 상태 Stream status

 

- 스트림의 마지막 연산에서 성공여부와 실패 원인에 대한 상태 정보를 저장함

 

C 와 C++ 에 같은 예문으로 한 번 비교해보자

 

if (fgets(line, 10, stdin) != NULL)
{
    // ...
}

----------------------------------------------------------------

cin >> line;

if (!cin.eof())
{
    // ...
}

 

C 에서 NULL 비교는 어떤 상태인지에 대해 명확하지 못해 직관적이지 않음

 

C++ 에서는 스트림 상태를 통해 어떤 상태인지 구변할 수 있음

 

iostream 상태

 

네임스페이스 = ios_base

비트플래그

  • goodbit = 아무 문제 없이 동작완료
  • eofbit = eof 맞났을 때
  • failbit = failbit 동작 와중에 fail 되었다
  • badbit = 동작중 문제가 발생

메소드 버전

  • good()
  • eof()
  • fail()
  • bad()

 

 

구분 예시)

int number;

cin >> number;

 

입력값 eofbit failbit  
456abc unset unset 456 까지 읽었으니 eof 와 fail 은 set 되지 않음
456 (un)set unset 입력할 때 456 과 같이 '/n ' 이 입력되는 환경에서와 같이 eof 로 인식되는 문자가 같이 입력되냐 안되냐에 따라 eof 비트 set 이 달라짐, fail 은 당연히 unset
abc unset set number 가 정수만 읽기 때문에 eof 와 숫자가 아닌 abc 를 못읽어서 eof 는 unset, fail 은 set
eof set set eof 를 읽기 때문에 eof 는 set, eof 는 number 에서 읽으려는 정수가 아니기 때문에 fail 도 set

 


입력버리기(Discarding Input)

 

입력 상태가 실패로 나타날 때, 실패된 입력을 버리고 새로운 입력을 받기 위한 행위

 

clear()

- 스트림을 좋은 상태(good state)로 돌려줌

cin.clear()

 

ignore()

- 아래 예제들과 파일 끝에 도달하거나 지정한 수만큼 문자를 버리면 멈춤

cin.ignore();  // 문자 1 개를 버림
cin.ignore(10); //  문자 10 개를 버림

cin.ignore(10, '\n') // 문자 10 개를 버림. 단, 그 전에 newline 문자를 버리면 곧바로 멈춤

cin.ignore(LLONG_MAX, '\n'); // 최대 문자 수를 버림. 단, 그 전에 newline 문자를 버리면 곧바로 멈춤 ( 한 줄을 다 버리는 기능)

 

get()

- 뉴라인 문자를 만나기 직전까지의 모든 문자를 가져옴

- 뉴라인 문자는 입력스트림에 남아있음

// 99 개 문자를 가져오거나 뉴라인 문자가 나올 때까지의 문자를 가져오고, 가져온 문자들을 char 배열(firstName) 에 배치

get(firstName, 100);

------------------------------------------------------------------

// 99 개 문자를 가져오거나 '#' 문자가 나올 때까지의 문자를 가져오고, 가져온 문자들을 char 배열(firstName)에 배치

get(firstName, 100, '#');

 

 

getline()

- 뉴라인 문자를 만나기 직전까지의 모든 문자를 가져옴

- 뉴라인 문자는 입력스트림에서 버림 ( get() 스트림에 그대로 두지만 getline() 삭제함)

getline(firstName, 100);
getline(firstName, 100, '#');

 

 

다음 정수의 합을 구하는 두 예문을 통해 활용 방법을 다시 확인해보자

 

예문1

#include <iostream>
#inlcude "AddIntegers.h"

using namespace std;

namespace samples
{
    void AddIntegersExample()
    {
        int number;
        int sum = 0;

        while (true)
        {
            cout << "Please enter an integer or EOF ";
            cin >> number;
            if (cin.eof())
            {
                break ;
            }
            if (cin.fail())
            {
                cout << "Invalid input" << endl;
                cin.clear();
                cin.ignore(LLONG_MAX, '\n');
                continue ;
            }
            sum += number;
        }
        cin.clear();

        cout << "The sum is " << sum << endl;
    }
}

 

예문2

#inlcude <iostream>
#inlcude "ReverseInputString.h"

using namespace std;

namespace samples
{
    void ReverseInputStringExample()
    {
        const int LINE_SIZE = 512;
        char line[LINE_SIZE];

        cout << "Please enter a string to reverse" << endl
            "or EOF to quit: ";

        cin.getline(line, LINE_SIZE);
        if (cin.fail())
        {
            cin.clear();
            return ;
        }

        char *p = line;
        char *q = line + strlen(line) - 1;
        while (p < q)
        {
            char temp;
            *p = *q;
            *q = temp;

            ++p;
            --q;
        }

        cout << "Reverse string: " << line << endl;
    }
}

 


[ TIP ]

 

>> 를 getline() 과 같이 혼용하는 것을 지양할 것

// 파일내용
// hello
// world

cin >> number;
getline(cin, line); // hello 뒤에 개행이 존재해서 getline 이 world 를 바로 읽어오지 못함

 

사용하게 된다면 다음과 같이 사용하는 방식이 있음

std::ws

cin >> number;
cin >> ws;	// ws 를 통해 개행을 버리기
getline(cin, line);

'C++ > FOCU_C++' 카테고리의 다른 글

C++ chpt6.  (1) 2025.05.16
C++ chpt5.  (0) 2025.05.04
C++ chpt4.  (0) 2025.05.03
C++ chtp3.  (0) 2025.05.03
C++ chpt1.  (0) 2025.04.28