본문 바로가기

코딩/객체지향프로그래밍

[C++] String, File - 문자열과 파일 (1)

출처: https://commons.wikimedia.org/wiki/File:File-folders.jpg

 


 

1. File(파일) 객체 - 소프트웨어 컴포넌트, 구성품 ex

  • sw component(구성품) 중 하나, 현재 프로그램 외부에 저장하는 데이터들을 file로 볼 수 있다.
  • 이 때 sw component를 객체(object) 또는 클래스(class)라고 부른다.
  • 객체(object) = 멤버 데이터(member data) + 멤버 함수(=member function or method) 로 구성

 

2. String(문자열)  객체 - 소프트웨어 컴포넌트, 구성품 ex

  • (마찬가지로 객체이기 때문에) 멤버 데이터(member data) + 멤버 함수(=member function or method) 로 구성
  • string객체의 메소드를 사용하려면 string 라이브러리를 include 해야 한다.
#include <iostream>
#include <string>
using namespace std;

int main() {
	string s; //문자열 선언
	s = "string 클래스의 객체 s"; //문자열 할당
}
  • string s: string class로부터 's'라는 instance(실체)를 만들었다 = string class로부터 's'라는 객체를 만들었다
  • 인스턴스화 한다: class로부터 실제로 구체화하여 instance(혹은 객체 라고도 함)를 만든다!!
  • string은 붕어빵 틀 - class 혹은 객체 라고도 불림
  • s는 붕어빵 - instance, 객체
  • " "로 감싸주기

*)대표적인 string 클래스의 메소드들

#include <iostream>
#include <string>
using namespace std;

int main() {
	string name = "홍길동";
    
	name.at(2); //인덱스 2(=3번째)에 해당하는 문자 '동' 반환
	name.length(); //문자열의 길이 3 반환
	name.size(); //문자열의 길이 3 반환 (length와 동일)
	name.find("길동"); //string 객체 name에서 원하는 문자열(substring)을 찾아 시작인덱스로 반환
	name.find("길동", 1); //찾을 시작 위치 지정도 가능, 1번째 문자부터 find
	name.substr(1, 2); //인덱스 1인 문자부터 2개의 문자 추출
	name.empty(); //문자열이 공백인지 확인, 공백이면 1(true) 아니면 0(false) 반환
	name.clear(); //name = ""; 빈 문자열로 만들어줌
}
  • 인덱스 i = i+1번째를 가리킴
  • string::npos : 정수가 표현할 수 있는 최댓값을 가지고 있는 변수 npos (size_t 자료형의 가장 큰 값), find메소드를 썼을 대 내가 찾는 문자열(substring)이 없으면 npos를 출력함

*)string method 활용 및 정리

#include <iostream>
#include <string>
using namespace std;

int main() {
	//string: string class 또는 string 객체
	//s: 객체 or instance
    
	string s = "fred";
	cout << "s: " << s << endl;
	cout << s.size() << endl <<endl;

	cout << "s: " << s << endl;
	cout << s.empty() << endl;
	s.clear();
	cout << "s: " << s << endl;
	cout << s.empty() << endl <<endl;

	s = "Good";
	s += "-bye"; //s = s + "-bye"; 덧셈 operator 지원
	//Good-bye
	//01234567 index - 각각의 문자에 대응(index는 항상 0부터, c++은 zero-based indexing)
	cout << "s: " << s << endl;
	cout << s[4] << ", " << s.at(4) << endl; //[]과 .at은 동일한 기능
    
	//[] : primitive(원래 있었던 거) 속도 빠름, 기계적으로 가져옴
	//.at : 함수, 속도 상대적으로 느림, 더 많이 씀, []보다 안전장치가 많아 예외상황 발생시 안정적
	

	cout << s.substr(5, 2) << endl; // index 5인 문자부터 2개의 문자 추출
	cout << s.substr(5, 3) << endl; 

	cout << s.find("od") << endl;
	cout << s.find("od", 5) << endl; //.find도 입력값 2개 가짐, (안적으면 defalt argument, 0) 
	
	cout << s.find("od", 5) << ", " << string::npos << endl;
	//찾고자 하는 문자가 있을/없을 경우에 따라 다르게 동작하는 program만들고 싶을 때
	//if(s.find("od", 5) == string::npos) {
	
	s += "-od";
	// Good-bye-od
	string key = "od";
	cout << "s: " << s << endl;
	int index = s.find(key);
	cout << index << endl;
	//두 번째 od를 찾고 싶을 때
	cout << s.find("od", index + key.size()) << endl; //[처음 찾은 od의 시작index + 크기] 뒤부터 찾기
	cout << (s == "good-bye-od") << endl; // false -> G,g 다른문자로 인식

	return 0;
}

 

3. 파일 stream 라이브러리, 메소드

1. 콘솔과 파일에서의 stream 차이

- console stream: 키보드로 입력 받고(cin) 모니터로 출력(cout)함 → 어디로 보내야 할 지 방향성이 정해져있음(cin은 키보드, cout은 모니터)

 

- file stream: fin과 fout은 어떤 file로 저장할지 목적지가 불확실함, 따라서 file을 명시해줘야 함 (ex) 현재 문자열들을 "example.txt"파일로 저장하겠다)

  • open함수로 어떤 파일로부터 읽어올 것인지, 어떤 파일에 저장할 것인지 이름 명시하기
  • 파일을 다 썼으면 반드시 close() 함수 써주기

- cout은 모니터(목적지)로 bit stream이 가는 것, fout은 파일(목적지)로 bit stream이 나감

 

2. 파일 stream과 기본적인 멤버 함수 (메소드)

- File Stream in C++

  • ifstream: 파일로부터 읽기
  • ofstream: 파일에 쓰기
  • fstream: 읽기 & 쓰기 둘 다 가능, (읽기 전용인지 쓰기 전용인지 헷갈려서 잘 사용하지 않음)

 

- Creating and Disconnecting File Streams

 

ㄱ. stream객체를 정의하기 (클래스로부터 객체 만들기, 인스턴스화!)

  • ifstream [stream 변수]
  • ofstream [stream 변수]
  • fstream [stream 변수]

ㄴ. 파일 stream 연결하기

  • open()

ㄷ. 파일 stream 연결 끊기

  • close()

 

4. 파일로부터 읽기, 파일에 쓰기

1. 한 줄씩 읽고 쓰기: 줄바꿈 문자('\n') 기준으로 끊음, 공백(white space)은 무시, EOF(End Of File)를 읽으면 종료

  • 읽기: getline(ifstream 객체, string 객체) ex) getline(fin, s)
  • 쓰기: ofstream 객체 << string 객체 ex) fout << s
#include <iostream>
#include <string>
#include <fstream> // ifstream ofstream 존재
using namespace std;

int main() {
	ofstream fout; //ofstream이라는 class의 fout이라는 instance
	fout.open("example.txt"); //덮어쓰기-기존의 파일 지우고 새로 씀
//	fout.open("example.txt", ios::app); //이어쓰기-app(append:추가)파일 끝에 내용 덧붙임
	string s = "Object oriented programming";

	fout << s << endl;
	fout << "Linear algebra" << endl;
	fout << "Random process" << endl;
	fout.close(); //open하면 반드시 close가 수반!!(of, if 모두)
	//콘솔에는 아무것도 출력x, 프로젝트 파일 안에 .txt로 저장돼있음

	ifstream fin; //읽기 객체
	fin.open("example.txt"); //어떤 file로부터 읽어올지, open으로 시작

	//예외처리
	if (!fin) { //파일을 제대로 열지 못했거나(잘못된 파일명) EOF를 읽으면 fin은 false
		cout << "File open error" << endl;
		exit(100); //프로그램 외부에서 강제종료(404error같이 시스템 종료 시 마지막 숫자)
	}

	while (getline(fin, s)) {
		// s = "Object oriented..";
		// s = "Linear algebra"; getline실행할 때마다 새로운 값 tracking, s에 덮어씀
		cout << s << endl;
	}
    
	fin.close();

	return 0;
}

 

2.  한 단어씩 읽고 쓰기: 공백(white space)과 줄바꿈 문자('\n') 기준으로 끊음, EOF(End Of File)를 읽으면 종료

  • 쓰기: ofstream 객체 << string 객체 ex) fout << s
#include <iostream>
#include <string>
#include <fstream> // ifstream ofstream 존재
using namespace std;

int main() {
	ofstream fout; //ofstream이라는 class의 fout이라는 instance
	fout.open("example.txt");
	string s = "Object oriented programming";

	fout << s << endl;
	fout << "Linear algebra" << endl;
	fout << "Random process" << endl;
	fout.close();

	ifstream fin;
	fin.open("example.txt");

	if (!fin) {
		cout << "File open error" << endl;
		exit(100);
	}

	while (true) {
		fin >> s;
		if (!fin) //fin이 EOF(end of file)를 읽으면 fin == false(!fin == true)
			break;
		cout << s << endl; //값을 잘 읽어왔는지 확인하기 위해 cout으로 화면에 뿌림
		//s는 fin으로 읽은거 저장,읽었던 시작위치를 간직하고 읽을 때마다 위치 update함, EOF 읽으면 종료
	}
    
	fin.close();


	return 0;
}

 

3. 한 문자씩 읽고 쓰기

  • 읽기: ifstream 객체.get(char 변수) ex) fin.get(ch)
  • 쓰기: ofstream 객체.put(char 변수) ex) fout.put(ch)
int main() {
	char ch;
	ofstream fout("char.txt"); //fout.open 따로 쓰지 않고 ofstream instance만듦과 동시에 file열 수 있음

	while (true) {
		cin >> ch;
		if (ch == 'q')
			break;
		fout.put(ch);
	}
	fout.close(); //open함수 안썼지만 동시에 열어줬으니까 닫아주기

	ifstream fin("char.txt"); // open도 함께
	cout << endl << endl;
	while (true) {
		fin.get(ch);
		if (!fin) // fin이 EOF를 읽으면 false
			break;
		cout << ch << endl;
	}
	fin.close();

	return 0;
}

 

 


 

*)sample codes: https://github.com/halterman/CppBook-SourceCode

반응형

'코딩 > 객체지향프로그래밍' 카테고리의 다른 글

[C++] 포인터, 벡터, 배열 (1)  (0) 2020.07.27
[C++] String, File - 문자열과 파일 (2)  (0) 2020.07.25
[C++] 조건문과 반복문 (2)  (0) 2020.07.21
[C++] 조건문과 반복문 (1)  (0) 2020.07.18
[C++] 함수(2)  (0) 2020.07.15