본문 바로가기
컴퓨터/C++_STL

파일 읽기 편하게 하기

by adnoctum 2013. 5. 1.




   텍스트 파일을 읽기 편하게 하기 위한 클래스를 만들어 보자. 간단한 사용 예는 다음과 같다. 


reader r;  std::set<std::string> all_compounds; while(r("compounds_in_treatment.txt",'#','\t')){ all_compounds.insert(r.begin()+2, r.end()); 


목적은 단순했다. while 문 안에 저렇게 해서 텍스트 파일을 한 줄씩 읽어들일 수 있게 하기 위한 것이었다. 더 이상 읽을 줄이 없거나 아니면 아예 애초에 파일을 열지 못했으면 false 가 반환되기 때문에 위처럼 해서 모든 줄을 읽을 수 있다. while 에 걸린 줄에 보면 첫 번째 인자는 파일 이름이고, 두 번째는 주석으로 간주할 줄이 제일 첫 칸에 어떤 문자가 있는지를 지정해 주는 것이고, 세 번째는 만약 텍스트 파일의 각 줄을 읽어서 tab 으로 자르고 싶으면 저렇게 해주면 되는 것이다. begin 이나 end 는 tab 으로 잘린 문자열 리스트를 vector 로 저장하고 있는데 그 벡터의 begin 과 end 를 반환하게끔 되어 있다. 


멤버 함수의 목록을 보자면 다음과 같다. 


reader();  virtual ~reader();  reader(const std::string& file_name);  std::string operator[](const int& index); bool read_line(const char& comment_mark); bool read_line(const char& comment_mark, const char& delimiter); std::vector<std::string>::const_iterator begin() const ; std::vector<std::string>::const_iterator end() const;  const std::string& get_line() const; const std::string& operator()() const; bool operator()(const std::string& file_name); bool operator()(const std::string& file_name, const char& comment_mark, const char& delimiter); bool close();


위 코드를 분석해 보면, operator[] 나 operator() 를 어떻게 재정의 해서 편리하게 사용할 수 있는지 알 수 있을 것이다. 위의 사용 예에는 안 나왔는데, 


r[1] 


과 같은 방식으로도 쓸 수 있다. 이것은, 읽은 줄을 delimiter 로 자른 후 두 번째 요소를 반환하는 것. 


전체 source 는 다음에 있다. 




1시간도 안걸려 후딱 만든 거라 고칠 부분이 좀 있을 것으로 생각한다. 일단 메모리 확인은 해 봤는데, valgrind 로 확인해 보면, 


==4349== HEAP SUMMARY:

==4349==     in use at exit: 0 bytes in 0 blocks

==4349==   total heap usage: 1,812,120 allocs, 1,812,120 frees, 157,495,929 bytes allocated

==4349== 

==4349== All heap blocks were freed -- no leaks are possible

==4349== 

==4349== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)


라고 나온다, 언제 봐도 기분 좋은, no leaks are possible, :)


이 클래스를 만들기 바로 전까지는 항상, 


std::ifstream hfile(file_name.c_str()); std::string line; while(std::getline(hfile, line)){ if(line == "" || line[0] == '#') continue; std::vector<std::string> v = split<std::string,string2string>(line, '\t'); std::set<std::string> cpd(v.begin() + 3, v.end()); compound_in_the_same_herb.push_back(cpd); }


이런 식으로 코딩을 했었지... 저 부분을 좀 줄여 보고 싶었다. 항상 반복되던 부분. 더구나 파이썬을 쓰다 보면 파일 읽는 부분이 파이썬에 비해 약간 번거로웠고, 그 약간이 반복되다 보니 좀 그랬다. 그래서 파이썬만큼 편리하게 만들어 보고 싶었지, ㅋ. 





   그래, 이런 클래스를 만들고 싶었어, ㅋ. 텍스트 파일을 열 때마다 항상 같은 코드가 반복되어서 만들어야지만들어야지 라고 생각만 하고 있다가, 지난 주말에 낮잠을 자려다 갑자기 생각이 난 이후 머릿 속에서 코딩을 한 번 죽 해보고, 오늘 일을 하다 갑자기 또 생각이 나서 후다닥 만들어 버렸다, ㅋ. 




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

포인터, 참조, 값 형식에 관한 개인적 관례  (0) 2014.05.09
포인터에 대한 짤막한 이야기  (2) 2014.04.02
const pointer  (0) 2011.11.23
isnan과 isinf  (0) 2010.12.06
동적 라이브러리 만들고 사용하기  (5) 2010.05.25