입력(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 |