승쨩개발공부
[C++] 입출력,스트림,버퍼,경로 본문
입출력(IO)
입력과 출력.
주체에 따라 입출력의 위치가 바뀐다.
프로그래밍에서 주체는 cpp파일, 실행파일이 주체가 된다.
입력
주체(파일)가 데이터를 받아오는 것.
출력
주체(파일)가 데이터를 내보내는 것.
입력 장치 : 키보드, 마우스 등
출력 장치 : 모니터, 스피커 등
스트림(Stream)
가상의 통로.
프로그램과 키보드, 프로그램과 모니터는 서로 연결되어있지 않다.
이러한 장치들을 서로 연결시켜주는 것이 스트림(통로)이다.
표준 스트림
stdin : 표준(std) 입력(in) 스트림(stream). 기본 키보드 대상
stdout: 표준 출력(out) 스트림. 기본 모니터 대상
stderr: 표준 오류(err) 스트림. 기본 모니터 대상
버퍼(Buff)
스트림 중간에 있는 메모리 블록
데이터 송수신의 효율성 떄문에 존재한다.
창고에서 집으로 물건을 옮길 떄 수레를 이용하면 더욱 편리하고 한번에 많은 물건을 옮길 수 있다.
버퍼는 수레 역할을 수행한다.
만약, 데이터를 입력 받는 통로(스트림)에 버퍼(수레)가 없을 경우
100이라는 값을 입력하기 위해서는 3개의 변수가 필요하고,
각각의 변수에 저장된 값들을 변환하여 100이라는 정수 값을 만들어야 한다.
버퍼가 존재할 경우 100이라는 값을 입력하면 버퍼에 1, 0, 0이 순차적으로 쌓이게 된다.
이후, 엔터를 이용해서 다 입력했다고 알려주는 순간 1, 0, 0이 100이라는 숫자로 변환되어
변수에 100이라는 값이 저장되게 된다.
문자/문자열 입출력(IO)
단일 문자 출력 함수
fPutc()
->fputc(77, stdout);
단일 문자 입력 함수
fgetc()
-> char ch = fgetc(stdin)
fputc(ch, stdout);
문자열 출력 함수
fputs()
-> fputs("Hello", stdout);
문자열 입력 함수
fgets()
-> char szBuff[16] = "";
fgets(szBuff, 16, stdin);
fputs(szBuff, stdout);
함수 호출 성공 및 실패 시 반환 값
함수 호출 성공 시 아스키코드의 정수 값을 반환
함수 호출 실패 시 EOF(End of File)를 반환
EOF?
파일의 끝을 표현하기 위해 정의해놓은 상수 (-1)
매개변수 및 반환타입이 int형인 이유
char 자료형은 시스템 환경에 따라 unsingned로 표현될 수 있다.
char 자료형이 unsigned가 될 경우 EOF를 표현할 수 없게 된다.
하지만 int 자료형은 어떠한 환경이든 signed를 유지한다.
경로(Path)
/ = 들어가서
.. = 나가서 (부모 디렉터리)
. = 현재 디렉토리
1.절대 경로
절대 경로(Absolute Path) 는 자신이 원하는 경로를 Root 디렉터리부터 모두 적은 것을 의미한다.
주체의 위치가 바뀌어도 목적지는 동일하다.
-> 안양시 안양동 xx번지 올리브영
-> D:/내문서/Visual Stdio/Projects/Project1/Data/
2.상대 경로
상대 경로(Relative Path) 는 특정 경로를 기준으로 다른 경로는 표시하는 개념
주체의 위치에 따라 목적지가 변하게 된다.
-> 동네 올리브영
-> ../Data/
스트림 개방
4 fopen_s(1, 2, 3)
1. 이중 포인터. 함수 내부에서 스트림을 생성하여 생성한 주소를 넣어줄 변수.
2. 경로. 문자열.
3. 모드. 입력 하기 위한 스트림인지, 출력하기 위한 스트림인지 등을 설정하는 것.(IO)
4. 결과. 스트림 개방에 성공하면 0을 반환, 실패 하면 이유 따른 값을 반환.
FILE* fp = nullptr;
//fopen_s(&fp, "D:/Visual Studio 2015/Projects/Project1/Data/Text.txt", "wt");
errno_t err = fopen_s(&fp, "../Data/Text.txt", "wt");
if (0 == err)
{
cout << "스트림 개방 성공!" << endl;
fclose(fp);
}
else
cout << "스트림 개방 실패!" << endl;
파일에 문자열 출력
FILE* fp = nullptr;
errno_t err = fopen_s(&fp, "../Data/Text.txt", "wt");
if (0 == err)
{
fputs("HelloWorld", fp);
cout << "스트림 개방 성공!" << endl;
fclose(fp);
}
else
cout << "스트림 개방 실패!" << endl;
// 파일에서 문자열 입력
char szBuff[16] = "";
FILE* fp = nullptr;
errno_t err = fopen_s(&fp, "../Data/Text.txt", "rt");
if (0 == err)
{
fgets(szBuff, 16, fp);
cout << "스트림 개방 성공!" << endl;
fclose(fp);
}
else
cout << "스트림 개방 실패!" << endl;
cout << "szBuff: " << szBuff << endl;
모드
w : Write의 약자 쓰기 모드일 떄 사용한다.
r : Read의 약자 읽기 모드일 떄 사용한다.
a : Append의 약자 이어 쓰기 모드일 떄 사용한다.
+ : 읽기/쓰기 모두 사용모드
-> 읽기에서 쓰기로, 쓰기에서 읽기로 작업을 변경할 떄 버퍼를 매번 비워주어야하는 불편함이 있다.
t : Text 모드일 떄 사용한다.
b : Binary 모드일 떄 사용한다.
Binary 모드의 장점
빠르다
Text로 읽을 수 없는 데이터도 입출력이 가능하다.
-> 그림, 영상, 음악 등
메모리 단위로 입출력이 가능하다.
-> 연속된 메모리를 사용할 경우 한번에 입출력할 수 있다.
Binary 모드의 주의사항
저장하는 데이터가 포인터일 경우 저장하지 말자.
바이너리 모드 출력 함수
5 fwrite(1, 2, 3, 4)
1. 포인터. 출력할 데이터의 시작 주소를 전달.
2. 시작 주소부터 얼마만큼 작업할 것인지 크기를 전달(byte단위)
3. 몇 개를 작업할 것인지 개수를 전달.
4. 어떤 스트림을 이용할 것인지 전달.
5. 입출력 성공 시 3번의 값을 반환. 입출력 실패시 3번의 값보다 작은 값을 반환
int iArr[5] = { 1, 2, 3, 4, 5 };
FILE* fp = nullptr;
errno_t err = fopen_s(&fp, "../Data/Binary.dat", "wb");
if (0 == err)
{
fwrite(iArr, sizeof(iArr), 1, fp);
fwrite(iArr, sizeof(int), 5, fp);
cout << "파일 개방 성공!" << endl;
fclose(fp);
}
else
cout << "파일 개방 실패!" << endl;
바이너리 모드 입력 함수
5 fread(1, 2, 3, 4)
1. 포인터. 입력할 데이터의 시작 주소를 전달.
2. 시작 주소부터 얼마만큼 작업할 것인지 크기를 전달(byte단위)
3. 몇 개를 작업할 것인지 개수를 전달.
4. 어떤 스트림을 이용할 것인지 전달.
5. 입출력 성공 시 3번의 값을 반환. 입출력 실패시 3번의 값보다 작은 값을 반환
int iArr[5] = {};
FILE* fp = nullptr;
errno_t err = fopen_s(&fp, "../Data/Binary.dat", "rb");
if (0 == err)
{
//fread(iArr, sizeof(iArr), 1, fp);
fread(iArr, sizeof(int), 5, fp);
cout << "파일 개방 성공!" << endl;
fclose(fp);
}
else
cout << "파일 개방 실패!" << endl;
for (int i = 0; i < 5; ++i)
cout << iArr[i] << endl;
예제
#include <iostream>
using namespace std;
void main()
{
FILE* fp_In = nullptr;
FILE* fp_Out = nullptr;
errno_t err_In = 0;
errno_t err_Out = 0;
err_In = fopen_s(&fp_In, "../Data/Image.jpg", "rb");
if (0 == err_In)
{
cout << "불러오기 성공!" << endl;
err_Out = fopen_s(&fp_Out, "../Data/Copy.jpg", "wb");
if (0 == err_Out)
{
char ch = 0;
while (true)
{
int iCnt = fread(&ch, sizeof(ch), 1, fp_In);
if (1 > iCnt)
break;
fwrite(&ch, sizeof(ch), 1, fp_Out);
}
cout << "내보내기 성공!" << endl;
fclose(fp_Out);
}
else
cout << "내보내기 실패!" << endl;
fclose(fp_In);
}
else
cout << "불러오기 실패!" << endl;
}
'C++' 카테고리의 다른 글
[C++] 공용체 (union) (0) | 2021.11.30 |
---|---|
[C++] 열거체(enum) (0) | 2021.11.30 |
[C++] 메모리 구조 (0) | 2021.11.30 |
[C++] 동적할당 (0) | 2021.11.29 |
[C++] Text RPG (0) | 2021.11.26 |