안녕하세요. 명월입니다.
이 글은 C++에서 IO(파일 읽기 쓰기)를 사용하는 방법에 대한 글입니다.
IO의 약어의 해석은 Input/Output의 뜻으로 사실 Input 장치인 키보드, 마우스 등등, Output장치인 모니터를 뜻하는 말입니다.
하지만 프로그램에서는 파일을 다루는 라이브러리를 통칭하는 의미합니다.
C++에서 파일을 읽고 쓰기에 대해서는 사실 굉장히 간단한 함수가 있습니다. fopen과 fwrite, fread를 통해서 사용할 수 있습니다.
// fopen, fwrite, fread를 최신 버전에서 사용하면 unsafe(안전하지 않은) 경고와 deprecation의 에러가 발생한다.
// 즉, 더이상 사용을 권하지 않는 뜻이다.
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <iostream>
using namespace std;
// 실행 함수
int main()
{
// 파일 리소스 포인터를 취득, 파라미터 w는 작성이다. (리소스 취득)
FILE* fp = fopen("d:\\work\\test.txt", "w");
// 포인터가 null이면 프로그램을 종료한다.
if (fp == NULL) {
cout << "File open failed" << endl;
return 1;
}
// 유니코드로 된 변수를 선언한다.
const wchar_t* data1 = L"hello world";
// 파일에 문자열을 작성한다. 유니코드라 사이즈는 2배이다.
fwrite(data1, 1, wcslen(data1) * 2, fp);
// 파일을 닫는다. (리소스 반환)
fclose(fp);
// 콘솔 출력
cout << "The file was created." << endl;
// 파일 리소스 포인터를 취득, 파라미터 r는 읽기이다. (리소스 취득)
fp = fopen("d:\\work\\test.txt", "r");
// 포인터가 null이면 프로그램을 종료한다.
if (fp == NULL) {
cout << "File open failed" << endl;
return 1;
}
// 파일 위치 포인터를 끝으로 이동한다.
fseek(fp, 0, SEEK_END);
// 위치 포인트의 위치를 리턴한다. 유니코드이므로 위치 * 2하면 파일 사이즈가 된다.
int size = ftell(fp) * 2;
// 파일 사이즈로 유니코드 char를 선언한다.
wchar_t* data2 = new wchar_t[size];
// 파일 위치 포인터를 앞으로 이동한다.
fseek(fp, 0, SEEK_SET);
// 파일을 읽는다.
fread(data2, 1, size, fp);
// 결과 콘솔 출력
wcout << "Result : " <<data2 << endl;
// 파일을 닫는다. (리소스 반환)
fclose(fp);
// 메모리 해제
delete data2;
return 0;
}
파일이 정상적으로 생성되고 읽어 왔습니다.
참조 - http://www.cplusplus.com/reference/cstdio/fopen/
그러나 이게 deprecation되어서 더이상 사용하기를 권장하지 않는다고 합니다. 그럼, 다른 방법으로 IO를 취득해서 파일을 읽고 작성해야 하겠습니다.
c++에는 IO를 다룰 수 있는 fstream 라이브러리가 있습니다.
#include <stdio.h>
#include <iostream>
// fstream을 include한다.
#include <fstream>
using namespace std;
// 실행 함수
int main()
{
// 유니코드로 된 변수를 선언한다.
const wchar_t* data1 = L"hello world";
// output stream을 선언한다. ※클래스 앞에 w가 붙는 건 유니코드 용이다.
wofstream ostream;
// d:\\work\\new.txt에 작성한다. , 디폴트 파라미터는 텍스트 파일이지만 바이너리를 다룰 때는 ios::binary를 추가한다.
ostream.open("d:\\work\\new.txt");
// 파일에 텍스트를 작성한다.
ostream << data1;
// stream를 닫는다. (리소스 반환)
ostream.close();
// 파일 사이즈를 구하기 위한 seek 위치를 구한다.
wstreampos begin, end;
// input stream을 선언한다.
wifstream istream("d:\\work\\new.txt");
// stream의 seek position을 구한다.
begin = istream.tellg();
// stream의 seek position을 파일 맨 끝으로 이동한다.
istream.seekg(0, ios::end);
// stream의 seek position을 구한다.
end = istream.tellg();
// stream의 seek position을 파일 앞 끝으로 이동한다.
istream.seekg(0, ios::beg);
// 파일 사이즈 구하기
int size = end - begin;
// 파일 내용을 담을 변수 선언
wchar_t* data2 = new wchar_t[size];
// 파일 내용을 변수에 담는다.
istream.read(data2, size);
// 결과 콘솔 출력
wcout << "Result : " << data2 << endl;
// stream를 닫는다. (리소스 반환)
istream.close();
// 메모리 해제
delete data2;
return 0;
}
파일이 정상적으로 생성되고 읽어 왔습니다.
참조 - http://www.cplusplus.com/doc/tutorial/files/
저도 C++를 사용 안 한 지가 벌써 10년이 되었습니다. 그 사이에 IO에 대한 사용법도 바뀌었네요.
개인적으로 fopen과 fread, fwrite도 편했는데.. 많은 문제가 있는 것 같습니다.
IO의 주요할 점은 꼭 close로 리소스를 반환 해야 합니다. 그렇지 않으면 성능상에 문제가 발생할 수 있습니다.
C++은 try finally가 없으니깐 조심해야 겠습니다.
여기까지 C++에서 IO(파일 읽기 쓰기)를 사용하는 방법에 대한 글이었습니다.
궁금한 점이나 잘못된 점이 있으면 댓글 부탁드립니다.
'Study > C , C++ , MFC' 카테고리의 다른 글
[C++] async, promise, future, task의 사용법 (1) | 2020.04.10 |
---|---|
[C++] map(맵)의 사용법 (0) | 2020.04.09 |
[C++] vector(리스트)의 사용법 (Stack, Queue 알고리즘 예제) (0) | 2020.04.08 |
[C++] 쓰레드(Thread)를 사용하는 방법 (0) | 2020.04.07 |
[C++] 예외처리(try ~ catch, throw) 사용법 (2) | 2020.04.04 |
[C++] 리터럴 문자열(const char*, const wchar_t*)과 typedef, operator의 사용법 (0) | 2020.04.02 |
[C++] 람다식(functional) 사용법과 클로저(closure) 그리고 auto 자료형 (0) | 2020.03.22 |
[C++] namespace와 using 사용법 (1) | 2020.03.20 |