[CPP-01] 파일 입출력 및 문자열 치환하기

이대현·2021년 4월 21일
1

C / CPP

목록 보기
18/28
post-custom-banner

[CPP-Module01 / ex07: Sed is for losers 과제]

  • FILENAME, 비어있지 않은 두개의 문자열 s1s2을 인자로 받는 replace 프로그램을 만들어라.

  • 이 프로그램은 주어진 파일을 오픈한 뒤 파일 내에 있는 문자열 s1을 s2로 변경한 FILENAME.replace 을 만든다.

  • 테스트 파일을 함께 제출해야한다.


1. fstream : 파일입출력 스트림

<iostream>을 사용하는 표준입출력과 마찬가지로 CPP의 파일입출력에는 ifstream, ofstream, fstream 세 가지 클래스가 사용된다. 각각 입력, 출력, 입출력을 위한 객체들이 정의되어 있으며, 표준입출력처럼 연산자 오버로딩을 통해 간단하게 사용할 수 있다. C처럼 함수이름을 외울필요가 없는 것이 장점이다.

std::cout << "Hello"; // 콘솔에 Hello 출력
std::out << "Hello"; // 파일스트림에 등록된 파일에 Hello 출력

과제에서는 인자로 주어진 파일을 읽은 뒤 내용을 변경한 새 파일을 만들어야하므로 include <fstream>을 한다.


2. open() : 스트림에 파일 연결하기

std::ifstream fin; // 파일스트림 객체 fin(file input)을 선언. fout도 마찬가지.
fin.open(filename);

open 멤버함수를 사용해 입출력에 사용할 파일과 프로그램 사이에 스트림을 만들어 준다. 아래 코드처럼 open을 생략하고 한줄로 줄여쓰는게 일반적인 것 같다.

std::ifstream fin(filename); 
std::ofstream fout(filename + ".replace"); 

3. is_open() : 예외처리 하기

파일을 읽을 때 파일이 존재하지 않을 수 있다. 아래 두 멤버함수를 예외처리를 위한 조건식으로 사용할 수 있다.

  • fail() : 해당 값이 true면 파일이 존재하지 않는다.
  • is_open() : 해당 값이 true면 파일이 존재한다.

4. RAII : 파일 연결 해제하기

fin.close();
fout.close();

하지만 CPP에서는 close 함수를 꼭 쓰지 않아도 된다. 소멸자가 스택에 할당된 자원은 스코프가 끝나면 자동으로 해지되기 때문이다. 이를 객체지향 프로그래밍에서는 RAII(Resource Acquisition Is Initialization)라고 부른다고 한다.


5. eof(), <<, >> : 파일에 문자열 읽고 쓰기

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' 을 기준으로 한 줄씩 읽어 객체에 저장

6. find() 및 replace() : 문자열 치환하기

문자열을 다루는 함수들이니 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);

6.1. find()와 npos

find(std::string str);

인자로 들어온 문자열이 line에 있다면 해당 문자열의 첫번째 인덱스를 반환한다. 만약 찾는 문자열이 없는 경우에는 std::string::npos를 반환한다. npos는 -1로 정의되는 상수라고 한다.

6.2. replace()

replace(size_type pos, size_type count, std::string str);

기존 문자열의 pos 부터 count 개의 문자들을 str로 치환한다.

profile
삽질의 기록들 👨‍💻
post-custom-banner

0개의 댓글