C++ Chapter 18.6 : 기본적인 파일 입출력
카테고리: Cpp
태그: Cpp Programming
인프런에 있는 홍정모 교수님의 홍정모의 따라 하며 배우는 C++ 강의를 듣고 정리한 필기입니다. 😀
🌜 [홍정모의 따라 하며 배우는 C++]강의 들으러 가기!
chapter 18. 입력과 출력
기본적인 파일 입출력
🔔 파일 출력 (Writing)
아스키 포맷으로 파일 출력 (디폴트)
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <cstdlib> // for exit();
using namespace std;
int main()
{
const string filename = "file.txt";
// Writing
if (true)
{
ofstream ofs(filename);
if (!ofs) { std::cerr << "Making file error\n"; exit(EXIT_FAILURE); }
for (char i = 'a'; i <= 'z'; ++i)
ofs << i ;
ofs << '\n';
}
}
it (true)
- 무조건 거치게 되어 있는 if문이다.
- 블록을 벗어나면 자동으로
ofs.close()
파일이 닫힐 수 있도록. - if(false)로 바꾸면 이 블록은 실행하지 않게 할수도 있으니 이렇게 if문에 넣어주면 편리하다.
ofstream ofs("file.txt)
- file.txt 파일을 출력 스트림으로 삼는다. 이 파일에 흘려 보내 write 할 것임을 나타낸다.
if (!ofs)
파일을 열 수 없다면ofs
는 nullptr일 것exit(1)
종료 시켜주기
for (char i = 'a'; i <= 'z'; ++i)
ofs << i ;
- a~z 까지의 문자를
ofs
스트림에 보낸다. file.txt에 a~z 문자가 쓰여 저장됨.
- 이제 프로젝트 위치와 같은 폴더에 가보면 file.txt 파일이 생겨있을 것이다!
바이너리로 파일 출력
- 아스키 포맷으로 파일을 출력하는건 엄청 느리다.
- 그래서 실무에선 바이너리로 저장하는 경우가 많다.
방법 1️⃣ ofstream의 write 사용
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <cstdlib> // for exit();
using namespace std;
int main()
{
const string filename = "file.txt";
// Writing
if (true)
{
ofstream ofs(filename);
if (!ofs) { std::cerr << "Making file error\n"; exit(EXIT_FAILURE); }
const unsigned num_data = 10;
ofs.write((char*)&num_data, sizeof(num_data));
for (int i = 0; i < num_data; ++i)
ofs.write((char*)&i, sizeof(i));
}
}
- 바이너리로 저장할 땐 데이터가 어디까지 저장되는지 알 수가 없기 때문에 데이터가 몇 개를 저장할지, 얼마의 크기로 저장할지 미리 약속해야 한다.
- 10개의 문자를 저장하고 싶다면
unsinged num_data = 10;
- 10개의 문자를 저장하고 싶다면
ofs.write(const char* str, streamsize n)
- write 함수
- 바이너리 값 그대로
ofs
에 출력된다. - 첫번째 인수
- char형 포인터나 주소값
(char*)&num_data
- num_data 의 주소를
char*
로 캐스팅하여 넘김
- num_data 의 주소를
- 두번째 인수
- 출력할 byte 수
sizeof(num_data)
- num_data 값만큼의 크기를 저장할거라고 약속하고 넘김
- 출력할 byte 수
- 바이너리 값 그대로
- ofs 스트림인 file.txt 에 “10”이 바이너리로 쓰여지고 저장된다.
for (int i = 0; i < num_data; ++i) ofs.write((char*)&i, sizeof(i));
- for문 10번 돌면서
- 0 1 2 3 4 5 6 7 8 9 가 바이너리로 file.txt.에 저장될 것.
- for문 10번 돌면서
- 최종적으로 file.txt 에 10 0 1 2 3 4 5 6 7 8 9 로 쓰여있음
- write 함수
방법 2️⃣ 파일 스트림 모드를 ios::binary로.
- ofstream ofs (“file.txt”,
ios:binary
)
🔔 파일 입력 (Reading)
아스키 포맷으로 파일 입력 ( 디폴트 )
ifstream ifs("file.txt")
- 프로젝트 위치와 같은 폴더에서 file.txt 파일을 파일 입력 스트림으로 불러온다.
if (!ifs)
- 파일을 열지 못 한다면. 오류. ifs에 nullptr 들어가있을 것. exit로 종료해주자.
getline(ifs, str);
- ifs 로부터 한줄 씩 읽어 들여 string str에 저장
- 파일 끝 EOF에 도달하면 ifs가 EOF가 되어 while문 빠져 나옴.
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <cstdlib> // for exit();
using namespace std;
int main()
{
const string filename = "file.txt";
// Reading
if (true)
{
ifstream ifs(filename);
if (!ifs) { std::cerr << "Opening file error\n"; exit(EXIT_FAILURE); }
while (ifs)
{
std::string str;
getline(ifs, str);
std::cout << str << endl;
}
}
}
바이너리 파일 입력
- 아스키 포맷으로 불러들이는건 너무 느리다
방법 1️⃣ ifstream의 read()이용
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <cstdlib> // for exit();
using namespace std;
int main()
{
const string filename = "file.txt";
// Reading
if (true)
{
ifstream ifs(filename);
if (!ifs) { std::cerr << "Opening file error\n"; exit(EXIT_FAILURE); }
const unsigned num_data = 0;
ifs.read((char*)&num_data, sizeof(num_data));
for (int i = 0; i < num_data; ++i)
{
int num;
ifs.read((char*)&num, sizeof(num));
std::cout << num << endl;
}
}
}
const unsigned num_data = 0
- 얼마 정도의 크기로 읽어 올지 아직 몰라서 0으로 초기화.
- 미리 file.txt에 숫자 몇개 읽어들일지를 크기를
num_data
에 저장해놓는다. - 10 0 1 2 3 4 5 6 7 8 9 로 쓰여있다고 가정. - 10 은num_data
에 - 0123456789 는num
에 불러와질 것. - 몇개 읽어 들일지 10으로 이렇게 앞에 써놓고 저장해놓기 ( 암묵적인 약속 )
ifs.read(const char* str, streamsize n)
ifs.read((char*)&num_data, sizeof(num_data));
- read 함수
- 바이너리 값 그대로 스트림으로부터 입력해온다.
- 첫번째 인수
- char형 포인터나 주소값
(char*)&num_data
- num_data 의 주소를 char*로 캐스팅하여 넘김
- 두번째 인수
- 입력할 byte 수. ifs인 file.txt로부터 num_data에 읽어들일 크기가 저장 된다.
sizeof(num_data)
- 추출할 문자의 크기.
- for문
- num 변수에 파일로 부터 읽어들여서
- 0 1 2 3 4 5 6 7 8 9 가 차례로 저장되고 각각 출력.
🔔 파일 모드
ios::app
- append 하기. 파일이 이미 존재할 경우에는 이어서 write.
ios::binary
- 바이너리 모드.
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글남기기