파일 스트림은 istream, ostream 클래스 보다 지원기능이 더 많고 이를 상속해서 사용한다.
그래서 이름이 ifstream, ofstream 이 됐다.
#include <fstream>
#include <iostream>
#include <string>
int main(){
// 파일 읽기 준비
std::ifstream in("test.txt");
std::string s;
if(in.is_open()){
in >> s;
std::cout<<"입력 받은 문자열 ::"<< s<< std::endl;
} else{
std::cout<<"파일이.. 없잖아!!!" << std::endl;
}
return 0;
}
std::ifstream in("test.txt");
: 읽을 파일의 경로를 지정한다.
in.is_open()
: 파일이 열렸는지 유무 확인가능
in >> s;
: in 객체를 사용해 파일을 읽을 수 있다.
ifstream 에서는 자동 fclose
를 해주기때문에 close를 꼭 안해줘도 된다.
근데 close를 해야하는 경우가 있다.
#include <fstream>
#include <iostream>
#include <string>
int main(){
// 파일 읽기 준비
std::ifstream in("test.txt");
std::string s;
if(in.is_open()){
in >> s;
std::cout<<"입력 받은 문자열 ::"<< s<< std::endl;
} else{
std::cout<<"파일이.. 없잖아!!!" << std::endl;
}
in.close();
in.open("other.txt");
if(in.is_open()){
in >> s;
std::cout<<"입력 받은 문자열 ::"<< s<< std::endl;
} else{
std::cout<<"파일이.. 없잖아!!!" << std::endl;
}
return 0;
}
#include <fstream>
#include <iostream>
#include <string>
int main(){
// 파일 읽기 준비
std::ifstream in("test.txt", std::ios::binary);
std::string s;
int x;
if(in.is_open()){
in.read((char*)(&x),4);
std::cout <<std::hex<<std::endl;
} else{
std::cout<<"파일을 찾을 수 없습니다." << std::endl;
}
return 0;
}
std::ifstream in("test.txt", std::ios::binary);
: 이렇게 binary 값으로 데이터를 받을 수 있다in.read((char*)(&x),4);
: 4바이트 내용을 읽어라 라는 내용char x[10]; in.read(x, 10);
이런식으로 배열을 지정해서 쉽게 코드를 짤 수 있음파일 전체를 한번에 읽어보자
#include <fstream>
#include <iostream>
#include <string>
int main(){
// 파일 읽기 준비
std::ifstream in("test.txt");
std::string s;
if(in.is_open()){
// 위치 지정자를 파일 끝으로 옮긴다.
in.seekg(0,std::ios::end);
// 그리고 그 위치를 읽는다. (파일의 크기)
int size = in.tellg();
// 그 크기의 문자열을 할당한다.
s.resize(size);
// 위치 지정자를 다시 파일 매 앞으로 옮긴다.
in.seekg(0, std::ios::beg);
// 파일 전체 내용을 읽어서 문자열에 저장
in.read(&s[0], size);
std::cout<<s<<std::endl;
} else{
std::cout<<"파일을 찾을 수 없습니다."<< std::endl;
}
return 0;
}
* 제가 참 좋아하는 노래 가사를 넣어봤어요
n.seekg(0, std::ios::end)
: fseek 함수인데 g(get) 포인터 함수 전용 seek 입니다.
int size = in.tellg()
: ftell 함수인데 g(get) 포인터 함수 전용 tell 입니다.
in.seekg(0, std::ios::beg)
: 파일크기를 파악했으니 위치지정자를 원상복구
in.read(&s[0], size);
: 파일 내용을 size만큼 읽어옵니다.
파일전체를 한줄 씩 읽어와보자
#include <fstream>
#include <iostream>
#include <string>
int main(){
// 파일 읽기 준비
std::ifstream in("test.txt");
char buf[100];
if(!in.is_open()){
std::cout<<"파일을 찾을 수 없어용" << std::endl;
return 0;
}
while(in){
in.getline(buf,100);
std::cout<<buf<<std::endl;
}
return 0;
}
잘된다.
in.getline(buf, 100)
: 한번에 buf에 99자 까지 받을 수 있다.
in.getline(buf, 100,'.')
: ' . ' 마다 끊어서 가져올 수 있다.while(in){ ... }
: in에서 받아오는 데이터가 없거나 성공적이 않으면 false가 나오고, 평소에는 true 가 나온다.
getline 을 할때, 개행문자가 나오기전에 버퍼가 가득 찰 수 있다.
그러면 failbit를 키게 되는데, 정상적으로 값을 받아올 수 없게 된다.
이런 한계점 또한 보완방안이 있는데
#include <fstream>
#include <iostream>
#include <string>
int main(){
// 파일 읽기 준비
std::ifstream in("test.txt");
if(!in.is_open()){
std::cout<<"파일을 찾을 수 없어용" << std::endl;
return 0;
}
std::string s;
while(in){
getline(in, s);
std::cout<<s<<std::endl;
}
return 0;
}
역시 잘나온다.
getline(in, s);
:
이 getline 함수는 ifstream에 정의되있지 않고, std::string
의 getline 이다.
| Tip! : while 문 '조건'으로 in.eof
사용금지
그냥 while(in)
을 하는게 좋음.#include <fstream>
#include <iostream>
#include <string>
int main(){
std::ofstream out("write.txt");
std::string s;
if(out.is_open()){
out << "Hello";
}
return 0;
}
저 파일이 없으면 저절로 생성된다.
덧붙이기도 가능하다.
#include <fstream>
#include <iostream>
#include <string>
int main(){
std::ofstream out("write.txt",std::ios::app);
std::string s;
if(out.is_open()){
out << "-Love never felt so good-";
}
return 0;
}
std::ofstream out("write.txt",std::ios::app);
이렇게 out 객체에 app을 주게되면, 파일에 스트림을 연결할때 지우지 새로안쓰고, 그대로 이어붙여 쓰게됨
저런 ios::binary
, ios::app
외에 몇 개 더있음
ios::ate
: 자동으로 파일끝에서 부터 읽기, 쓰기를 실시한다.(기존내용은 삭제해버림)ios::trunc
: 파일스트림을 열면 기존에 열던 내용들이 모두 지워짐.ios::in
ios::out
: 파일에 입력 할 지 출력 할 지 지정가능하다.#include <iostream>
#include <sstream>
int main(){
std::istringstream ss("123");
int x;
ss>>x;
std::cout<<"입력받은 데이터 ::"<< x <<std::endl;
return 0;
}
string으로 숫자입력을해서 받아왔다.
sstream 에는 std::istringstream 이 정의되었음. 문자열을 하나의 스트림이라고 생각하게 해주는 가상화 장치라고 보면 됨.
std::istringstream ss("123");
"123"
string 을 받았지만, 123
숫자로 입력받는 것과 동일한 효과를 낸다.int x;
ss >> x;
#include <iostream>
#include <sstream>
double to_number(std::string s){
std::istringstream ss(s);
double x;
ss>>x;
return x;
}
int main(){
std::cout<<"변환하자 :: 1.2 + 2 = "<< to_number("1.2") + to_number("2")<< std::endl;
return 0;
}
그럼 반대로 숫자를 string으로 바꿔보자
#include <iostream>
#include <sstream>
#include <string>
std::string to_str(double x){
std::ostringstream ss(x);
ss<<x;
return ss.str();
}
int main(){
std::cout<<"문자열로 변환 :: 1.2 + 2 = "<<to_str(1.2+2)<< std::endl;
return 0;
}
std::ostringstream ss;
ss << x;
return ss.str();