파일 입출력(fstream)

2020. 9. 14. 00:14컴퓨터 수업/C++

@라이브러리

#include <fstream>

@사용할 클래스

ifstream  (in fstream)   // data로부터 내 프로그램으로 in

ofstream (out fstream) // 내 프로그램으로부터 data로 out

 

@사용할 메소드

open // 파일을 연다.

>> 입력

<< 출력

get, put

 

@알고 있어야 하는 사실

생성된 객체는 boolean값을 가진다, 0일 때는 읽거나 쓸 수 없음이고, 1일 때는 가능하다는 뜻이다.

 

@객체 생성

ifstream infile("data.txt");
ofstream outfile("data2.txt");

infile과 outfile은 내가 지은 이름이다. 객체의 이름이 될 것이다. 그 후 argument는 생성자를 이용해 파일을 open 한 것이다.

 

ifstream infile;
infile.open("data.txt");

ofstream outfile;
outfile.open("data2.txt");

따라서 위와 같이 open이라는 메소드를 이용해서 파일을 열 수도 있다.

 

@boolean 값을 이용한 error여부 확인

if(!infile)
{
cout << "Cant open the file !" <<endl;
exit(1);
}

@예제

1. 사용할 데이터

2. 데이터 입력받는 3가지 방법

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
	ifstream infile;
	infile.open("data.txt");

	if (!infile)
	{
		cout << "Cant open the file" << endl;
		exit(1);
	}



	cout << "infile 객체에 >> 연산자를 이용" << endl;  //        1
	char* str = new char[10];
	for (int i = 0;i < 4;i++)
	{
		infile >> str;
		cout << str << endl;
	}
	cout << "get 함수를 이용, 한글자씩 읽는다" << endl;//         2
	char ch;
	while (infile)
	{
		infile.get(ch);
		cout << ch;
	}



	return 0;
}

 

참고로 이 코드의 두 가지 방법은 동시에 실행되진 않는다,  1에서 이미 끝까지 읽었기 때문에 2는 실행할 수 없다.

 

===2020-09-18 수정

@그래서 ifstream이랑 ofstream이 뭔데?

겁먹지 말고 일단 보자, 이는 class의 계층구조를 나타내는 것인데, fstream class는 왼쪽에 있는 class들에서 상속받았다. (inherited from) 따라서, 왼쪽에 있는 객체들의 멤버 함수를 사용할 수 있다.

 

@몇몇 사용처를 볼까?

#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char* argv[])
{
	ifstream input_file(argv[1], ios::binary);
	ofstream output_file(argv[2], ios::binary);

	char ch;

	while (input_file.get(ch))
	{
		if (input_file.bad())break;
		if (ch == 0x0D)
			output_file << char(0x0D) << char(0x0A);
		else
			output_file << ch;
	}
	input_file.close();
	output_file.close();
}

@먼저 한 글자씩 읽어서 마지막을 읽었을 때, 동작을 그만두는 작업을 while(input_file.get(ch))를 통해 나타냈다.

원래는

while(input_file)
{
get(ch);
}

를 사용하려고 하였으나, Hello World를 읽었을 때, Hello Worldd라고 출력되는 문제점이 존재했다.

이는 아무래도 currentPos 문제와 유사하다고 생각한다.

예를 들어, GetNextItem 메소드가 다음과 같이 구성되어 있다고 생각해보자.

currentPos++;
GetNextItem();
현재 Position의 값이 true한지 false한지 boolean으로 return

그렇다면, 마지막 문자에 접근-> 그 문자 return -> 현재 pos에 값이 있으니 true 따라서 while문이 다시 실행되고, 그다음 문자에 접근(NULL) -> 마지막 문자를 다시 return -> 현재 pos에 값이 없으니 false 따라서 while문이 종료.

이렇게 마지막 문자가 다시 2번 return 된다고 생각한다.

 

#참고로 위 코드는 CR을 CRLF로 바꾸는 코드이다. 0x0D가 아스키코드로 CR('\r'), 0x0A가 LF('\n')이다.

#binary로 안 읽으면, Window에서 LF를 CRLF로 읽고, LF를 CRLF로, CR을 CRLF로 출력하는 문제가 발생하기에 ios::binary로 읽거나 써야한다.

'컴퓨터 수업 > C++' 카테고리의 다른 글

빌드,컴파일  (0) 2020.09.18
main함수의 아규먼트// argc & argv  (0) 2020.09.18
const에 관한 얘기  (0) 2020.09.13
연산자 오버로드(operator overload)//ostream 나중에 채워넣기  (0) 2020.09.10
friend 함수  (0) 2020.09.10