2024. 3. 3. 18:07ㆍProgramming Language/C++
아래 링크 클릭 시 해당 본문으로 이동
C의 입출력 방식
헤더 파일
// C 방식
#include <stdio.h> // stdio.h => global namespace
// #include : 내가 원하는 다른 기능을 포함시킨다는 의미, 전처리기이다.
// stdio : standard input output (표준 입출력)
// .h : 헤더 파일(header file)을 의미하는 확장자
// C++ 방식
#include <cstdio> // cstdio => std라는 namespace
printf()
와 scanf()
를 사용하려면 #include <stdio.h>
라는 표준 입출력 헤더 파일이 필요하다.
printf()
• 출력(print) + 형식(formatted)
서식화된 출력을 지원한다는 의미이다.
• 표준 출력 함수
보통 문자열을 출력할 때 사용한다.
• 콘솔 창에 원하는 데이터를 서식 지정자에 맞게 출력할 수 있다.
• 첫 번째 인자 : printf()
에 출력하고 싶은 자료형의 서식 지정자
• 두 번째 인자 : 첫 번째 인자로 넣은 서식 지정자에 해당하는 값 (넣고 싶은 값)
▷ 예시
#include <stdio.h>
int main()
{
printf("abc %d\n", 10); // abc 10
printf("abc %f\n", 3.25f); // abc 3.250000
return 0;
}
%d
자리는 정수 10
으로, %f
자리는 실수 3.250000
으로 대체됐다.

콘솔(console) 창
• 입출력할 수 있는 창
• main()
가 실행되면 콘솔 창이 나타난다.

이스케이프 시퀀스(\n), 형식 지정자(%d, %f)는 해당 본문 아래 페이지 참고
• 이스케이프 시퀀스
• 형식 지정자
scanf()
• scan(데이터를 읽고 처리한다.) + 형식(formatted)
서식화된 입력을 받다는 의미이다.
• 콘솔 창으로부터 입력을 받아 지정한 변수에 저장하는 함수
• scanf()
를 쓸 때 scanf_s
로 써야 한다. (safe 버전)
▷ 예시
#include <stdio.h>
int main()
{
int k = 0;
// 변수 k에 넣을 정수형 값 입력
scanf_s("%d", &k); // 정수형(%d)을 입력받아서 k에 저장한다.
return 0;
}

콘솔 창이 입력한 내용을 받아와서 지정한 변수에 저장하는 것이 scanf()
의 기능이다.
때문에 코드를 실행하면 콘솔 창이 입력을 기다린다.
콘솔 창에 50을 입력하고 엔터를 누르면 지정한 변수 k
에 50이 저장된다.

↓

scanf_s()
에서 변수의 주소로 접근한 이유
(scanf()
보다 좀 더 안전한 scanf_s()
를 사용할 것이기 때문에 scanf_s()
라고 표현하겠다.)
scanf_s()
는 콘솔 창에 입력한 데이터를 지정한 변수에 넣어주는 역할을 하는 함수이다.
다시 말해 콘솔 창으로부터 입력된 값을 전달해준 주소로 접근해서 넣어주는 함수이다.
#include <stdio.h>
void Test(int* a)
{
*a = 500; // a의 주소에 접근해서 값을 500으로 바꾼다.
}
int main()
{
int a = 100;
Test(&a); // a의 주소를 Test() 함수에 넣는다.
printf("출력 : %d\n", a); // 출력 : 500
scanf_s("%d", &a);
return 0;
}
scanf()_s
가 변수 앞에 &
를 붙여서 주소를 요구했던 이유도 이 때문이다.
값을 넣었을 때 a
값이 500이 아닌 100이 나왔던 것처럼 변경된 값이 적용되지 않을 수도 있으므로 주소로 접근해서 확실하게 값을 넣어준다.
scanf_s()
가 종료되면 그때 a
값이 바뀐다.
scanf_s()
에서 콘솔 창에 700을 입력하고 엔터를 누르면 a
값이 700으로 변경된다.

이스케이프 시퀀스(escape sequence)
• 프로그램 결과가 화면에 출력될 때 사용할 특수한 문자를 위해 만들어졌다.
\' | 작은 따옴표(') |
\" | 큰 따옴표(") |
\? | 물음표(?) |
\\ | 백슬래시(\) |
\a | 경고음 발생 |
\b | 백 스페이스(backspace) |
\n | 줄 바꿈 |
\r | 캐리지 리턴(carriage return) |
\t | 수평 탭(tab) |
\v | 수직 탭(tab) |
\f | 폼 피드(form feed) |
형식 지정자
형식 지정자 | 자료형 | 의미 |
문자열 | ||
%c | char | 문자 하나 |
%s | char*, char[ ] | 문자열 |
정수 | ||
%hd 또는 %hi |
short | (부호 O) 10진 정수 |
%hu | unsigned short | (부호 X) 10진 정수 |
%ho | unsigned short | (부호 X) 8진 정수 |
%hx | unsigned short | (부호 X) 16진 정수 (소문자 표기) |
%hX | unsigned short | (부호 X) 16진 정수 (대문자 표기) |
%d | int | (부호 O) 10진 정수 |
%i | int | (부호 O) 10진 정수 |
%u | unsigned int | (부호 X) 10진 정수 |
%o | unsigned int | (부호 X) 8진 정수 |
%x | unsigned int | (부호 X) 16진 정수 (소문자 표기) |
%X | unsigned int | (부호 X) 16진 정수 (대문자 표기) |
%ld | long | (부호 O) 10진 정수 |
%li | long | (부호 O) 10진 정수 |
%lu | unsigned long | (부호 X) 10진 정수 |
%lo | unsigned long | (부호 X) 8진 정수 |
%lx | unsigned long | (부호 X) 16진 정수 (소문자 표기) |
%lX | unsigned long | (부호 X) 16진 정수 (대문자 표기) |
%lld | long long | (부호 O) 10진 정수 |
%lli | long long | (부호 O) 10진 정수 |
%llu | unsigned long long | (부호 X) 10진 정수 |
%llo | unsigned long long | (부호 X) 8진 정수 |
%llx | unsigned long long | (부호 X) 16진 정수 (소문자 표기) |
%llX | unsigned long long | (부호 X) 16진 정수 (대문자 표기) |
실수 | ||
%f | float | 실수 → 고정 소수점 표현 (10진수, 소문자 표기) (소수점 아래 6자리까지) |
%F | float | 실수 → 고정 소수점 표현 (10진수, 대문자 표기) (소수점 아래 6자리까지) |
%e | float | 실수 → 부동 소수점 표현 (10진수, e-표기법) |
%E | float | 실수 → 부동 소수점 표현 (10진수, E-표기법) |
%g | float | %f 또는 %e 중 짧은 것 사용 (소문자 표기) |
%G | float | %F 또는 %E 중 짧은 것 사용 (대문자 표기) |
%a | float | 실수 → 지수 표현 (16진수, 소문자 표기) |
%A | float | 실수 → 지수 표현 (16진수, 대문자 표기) |
%lf | double | 실수 → 소수점 표현 (10진수, 소문자 표기) |
%le | double | 실수 → 지수 표현 (10진수, 소문자 표기) |
#lE | double | 실수 → 지수 표현 (10진수, 대문자 표기) |
%lg | double | %lf와 %le 둘 중 짧은 것 사용 (소문자 표기) |
%lG | double | %lf와 %le 둘 중 짧은 것 사용 (대문자 표기) |
%llf 또는 %Lf |
long double | 실수 → 소수점 표현 (10진수) |
%Le | long double | 실수 → 지수 표현 (10진수, 소문자 표기) |
%LE | long double | 실수 → 지수 표현 (10진수, 대문자 표기) |
%La | long double | 실수 → 지수 표현 (16진수, 소문자 표기) |
%LA | long double | 실수 → 지수 표현 (16진수, 대문자 표기) |
포인터 | ||
%p | - | 포인터(pointer) 메모리 주소 |
% 기호 | ||
%% | - | 퍼센트(%) 기호 출력 |
플래그 | ||
%숫자 | - | • 숫자만큼의 폭을 출력 • 오른쪽 정렬(기본) |
%.숫자 | - | • 온점(.) 뒤의 숫자만큼 소숫점 자릿수 조절 • 나머지는 반올림 |
%- | - | 왼쪽 정렬 |
%+ | - | • 음수일 때만 표현되던 부호 → 양수에서도 표현 • 양수일 경우 ➜ '+' 부호 |
%# | - | • 출력되는 숫자 앞 → 진법 표기 • 실수일 경우 ➜ 소수점을 강제로 붙임. (%#o, %#x, %#X, %#f, %#F, %#e, %#E, %#g, %#G) |
%0숫자 | - | • 숫자만큼의 폭을 지정 • 빈칸 ➜ 0으로 채움. |
C++의 입출력 방식
헤더 파일
#include <iostream>
+) 디스어셈블리 - cin, cout
// _PURE_APPDOMAIN_GLOBAL extern _CRDATA2_IMPORT istream cin;
// _PURE_APPDOMAIN_GLOBAL extern _CRDATA2_IMPORT ostream cout;
// extern 키워드가 붙은 이유 : iostream이라는 헤더 파일을 참조하면 모든 파일은 해당 변수를 알게 된다.
cin, cout 기본 형식
std::cin
std::cout
cout
• 데이터를 출력하는 데 사용되며, 출력 스트림을 나타내는 객체
• istream 클래스의 전역 변수명(객체명)
cout 문법
cout << 출력할데이터;
삽입 연산자(<<
)는 출력할 데이터를 출력 스트림에 삽입하고, 출력 스트림에 삽입된 데이터는 스트림을 통해 출력 장치로 전달되어 출력된다.
cin
• 데이터를 입력받는 데 사용되며, 입력 스트림을 나타내는 객체
• cin 객체는 자동으로 사용자가 입력한 데이터를 변수의 타입과 동일하게 변환시켜 준다.
• ostream 클래스의 전역 변수명(객체명)
cin 문법
cin >> 입력데이터를저장할변수;
추출 연산자(>>
)로 사용자가 입력한 데이터를 입력 스트림에서 추출하여 변수에 저장한다.
※ >> 방향 주의
변수에 데이터를 집어넣는 모습을 생각하면 쉽다.
C 표준 입출력(printf()
, scanf()
) vs C++ 표준 입출력(cin
, cout
)
특징 | C 표준 입출력 printf(), scanf() |
C++ 표준 입출력 cin, cout |
라이브러리 | C 표준 라이브러리 (stdio.h) |
C++ 표준 라이브러리 (iostream) |
형태 | 함수 | 객체 |
C 및 C++에서의 사용 가능 여부 |
C, C++에서 사용 가능 | C에서는 사용 불가능하고, C++에서만 사용할 수 있다. |
구문 | 형식 지정자 사용 (ex. %d, %f) |
연산자 오버로딩 사용 (>>, <<) |
입출력 스트림 | 표준 스트림(stdin, stdout)과 함께 작동한다. | 입출력 스트림 객체(cin, cout, cerr 등)를 사용한다. |
확장성 | 사전에 정의된 형식에만 제한된다. | 연산자 오버로딩을 통한 사용자 정의 타입을 지원한다. |
처리 속도 | 최소한의 오버헤드로 인해 일반적으로 더 빠르다. | 추가적인 안전성과 기능으로 인해 printf(), scanf()에 비해 느리다. |
컴파일러 검사 | 데이터의 자료형을 검파일러가 검사할 수 없어서 버그가 발생할 확률이 높다. | 데이터의 자료형을 컴파일러가 검사한다. |
오류 처리 | 오류를 확인하기 위해 반환값을 제공한다. | 스트림 상태(cin.fail() 등)를 직접 확인할 수 있다. |
• printf()
, scanf()
는 형식화된 입출력에 효율적이지만 형식 지정자를 신중히 정해야 한다.
• cin
, cout
은 속도는 느리지만 비교적 최근에 나와 안전성과 확장성 면에서 더 뛰어나다.
cin
, cout
속도 향상 시키는 법
• 불필요한 flush가 호출되지 않게 endl
보다 \n
을 사용한다.
• flush
출력 스트림 맨 뒤에 줄 바꿈 문자를 추가하지 않고 출력 스트림 내부 버퍼에 있는 데이터를 모두 비우는 동작
• C 표준 입출력 방식 사용하기
• 버퍼 동기화 끊기
일종의 편법으로 아래 코드를 main()
에 추가함으로써 버퍼 동기화를 끊고 tie를 풀어주면 된다.
• tie
서로의 I/O 작업 전에 버퍼를 자동으로 비운다.
단, 버퍼 동기화를 끊으면 cin
, cout
를 쓰면서 printf()
, scanf()
를 같이 쓸 수 없고, 이 방식이 통하지 않는 경우도 발생할 수 있기 때문에 추천하지는 않는다.
// main() 맨 윗줄에 추가하기
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
'Programming Language > C++' 카테고리의 다른 글
[C++] 호출 스택, 반복문 vs. 재귀함수[팩토리얼, 피보나치 수열], 꼬리 재귀 (0) | 2024.03.04 |
---|---|
[C++] 반복문, 반복문 탈출 방법 (0) | 2024.03.03 |
[C++] 함수[main()], return, void (0) | 2024.03.03 |
[C++] 메모리 영역, 변수 (0) | 2024.03.02 |
[C++] 조건문(Conditional Statements), 삼항 연산자 (0) | 2024.02.29 |