[CPP-Module01 / ex07: Sed is for losers 과제]
FILENAME
, 비어있지 않은 두개의 문자열 s1
과 s2
을 인자로 받는 replace
프로그램을 만들어라.
이 프로그램은 주어진 파일을 오픈한 뒤 파일 내에 있는 문자열 s1을 s2로 변경한 FILENAME.replace
을 만든다.
테스트 파일을 함께 제출해야한다.
<iostream>
을 사용하는 표준입출력과 마찬가지로 CPP의 파일입출력에는 ifstream
, ofstream
, fstream
세 가지 클래스가 사용된다. 각각 입력, 출력, 입출력을 위한 객체들이 정의되어 있으며, 표준입출력처럼 연산자 오버로딩을 통해 간단하게 사용할 수 있다. C처럼 함수이름을 외울필요가 없는 것이 장점이다.
std::cout << "Hello"; // 콘솔에 Hello 출력
std::out << "Hello"; // 파일스트림에 등록된 파일에 Hello 출력
과제에서는 인자로 주어진 파일을 읽은 뒤 내용을 변경한 새 파일을 만들어야하므로 include <fstream>
을 한다.
std::ifstream fin; // 파일스트림 객체 fin(file input)을 선언. fout도 마찬가지.
fin.open(filename);
open
멤버함수를 사용해 입출력에 사용할 파일과 프로그램 사이에 스트림을 만들어 준다. 아래 코드처럼 open을 생략하고 한줄로 줄여쓰는게 일반적인 것 같다.
std::ifstream fin(filename);
std::ofstream fout(filename + ".replace");
파일을 읽을 때 파일이 존재하지 않을 수 있다. 아래 두 멤버함수를 예외처리를 위한 조건식으로 사용할 수 있다.
fail()
: 해당 값이 true면 파일이 존재하지 않는다.is_open()
: 해당 값이 true면 파일이 존재한다.fin.close();
fout.close();
하지만 CPP에서는 close
함수를 꼭 쓰지 않아도 된다. 소멸자가 스택에 할당된 자원은 스코프가 끝나면 자동으로 해지되기 때문이다. 이를 객체지향 프로그래밍에서는 RAII
(Resource Acquisition Is Initialization)라고 부른다고 한다.
cout으로 콘솔에 출력했던 것처럼, <<
과 >>
연산자를 쓰면 된다. eof()
함수는 파일이 끝나면 1을 반환한다.
#include <iostream>
#include <fstream>
int main()
{
ifstream fin("sample.txt"); // 읽을 파일을 fin 스트림객체와 연결한다.
std::string line;
while (!fin.eof())
{
fin >> line; // >> 연산자는 white space나 '\n'을 기준으로 읽는다.
std::cout << line << std::endl;
}
return (0);
}
그 외에도 아래 함수들이 존재한다.
put('A')
: 한 글자씩 쓰기get()
: 한 글자씩 읽기getline(fin, 입력받은 문자열을 저장할 string 객체)
: 입력스트림으로부터 '\n' 을 기준으로 한 줄씩 읽어 객체에 저장문자열을 다루는 함수들이니 string
클래스를 include 한다.
include <iostream>
include <string>
if (line.find(s1) == std::string::npos)
std::cout << "해당 line에 s1 문자열이 없음" << std::endl;
else
line.replace(pos, s1.length(), s2);
find(std::string str);
인자로 들어온 문자열이 line에 있다면 해당 문자열의 첫번째 인덱스를 반환한다. 만약 찾는 문자열이 없는 경우에는 std::string::npos
를 반환한다. npos
는 -1로 정의되는 상수라고 한다.
replace(size_type pos, size_type count, std::string str);
기존 문자열의 pos
부터 count
개의 문자들을 str
로 치환한다.