(C++) 스마트팩토리 - 16일

내 이름 안찬찬·2023년 2월 7일
0
post-thumbnail

namespace

namespace란?

  • 식별자를 더 잘 구분하여 오류를 최소화하기 위한 기능
프로젝트가 커지고, 여러 파일, 여러 개발자가 나눠서 개발을 하게 되면,
식별자(변수, 함수 등의 이름)의 이름이 같아져 충돌이 일어날 확률이 높아짐. 
이런 충돌이 발생하지 않기 위해 만들어진 것이 namespace 개념

namespace (이름 공간)

namespace (namespace 이름) {
}
using namespace 네임스페이스 이름;
// namespace내에 있는 모든 요소의 접근을 풀어 줌.
using 네임스페이스::식별자;
// namespace내에 특정 요소의 접근을 풀어 줌

namespace 예시

#include <iostream>
// std namespace 내에 있는 모든 요소에 대한 접근을 풀어준다.
//using namespace std; 
// 개별로 푸는 방법
using std::cout;
using std::cin;
using std::endl;


namespace ns_test {
	int num = 0;
	namespace ns_test1 {
		int num = 1;
	}
	void test() {
		cout << num << endl;
		cout << "hello world" << endl;
	}
}

void bbb() {
	// num 인식불가
	//num = 10;
	ns_test::num = 15;
	cout << "bbb";
}

using namespace ns_test;



void aaa() {
	num = 7;
	cout << "aaa: " << num;
}

int main(){
	// namespace에서 가져온 num
	//num = 1;  //ns_test::num = 1; 어떤 num인지 구분하기 쉽지 않아서 추천X

	cout << ns_test::num << endl;
	//  using namespace ns_test; 선언
	cout << num << endl; 

	test();
	aaa();
	cout << endl;
	
	num = 5;
	cout << num << endl;
	ns_test::ns_test1::num; // 네임스페이스 안에 네임스페이스

}

namespace 실습 1

(1) 'seoul' 을 나타내는 namespace 를 만들고 그 안에 '지역번호', '랜드마크' 을 의미하는 변수를 각각 만드세요.

(2) 'busan' 을 나타내는 namespace 를 만들고 그 안에 '지역번호', '랜드마크' 을 의미하는 변수를 각각 만드세요.

(3) '지역번호'와 '랜드마크'을 의미하는 변수의 이름은 'seoul' namespace 와 'busan' namespace 가 동일해야 합니다.

(4) main 함수 안에서 위의 namespace 에 있는 변수에 원하는 값을 할당하고 출력하도록 하세요.

(5) busan namespace는 using 사용해보기

#include <iostream>
#include <string>
using std::cout;
using std::cin;
using std::endl;


namespace seoul {
	int addr = 2580;
	std::string land = "경복궁";

	namespace busan {
		int addr = 3910;
		std::string land = "롯데월드";
	}
}

using namespace seoul::busan;

int main() {

	cout << "부산 지역번호: " << addr << endl;
	cout << "부산 랜드마크: " << land << endl;

	cout << "서울 지역번호: " << seoul::addr << endl;
	cout << "서울 랜드마크: " << seoul::land << endl;
}


파일 입출력

fstream

  • 파일을 읽고, 쓸 수 있도록 관련 기능을 제공하는 헤더
#include <fstream>

fstream - 기본 메소드

.open("파일 명"); // 파일 명에 해당하는 파일 열기
.fail(); // 파일이 잘 열렸는지 확인. 파일 열기에 실패 했다면 true.
.close(); // 파일 닫기.

ifstream

  • 파일의 내용을 가지고 와서 프로그램에 입력할 수 있게 도와주는 클래스
  • 파일 -> 프로그램
std::ifstream file; // 파일을 담을 변수 선언
file.open("test_file.txt"); // test_file.txt이라는 파일 열기
std::ifstream file("test_file.txt"); // 파일을 담을 변수 선언과 동시에 파일 열기

ifstream - 내용읽기

std::ifstream file("test_file.txt");
string str, line; 
file >> str; // 띄어쓰기 전까지 읽어서 str에 저장
std::getline(file, line); // 엔터 전까지 읽어서 line에 저장
int main() {
	//기존 텍스트파일 읽어오는 방법
	//std::ifstream
	ifstream file;
	file.open("file_test.txt"); //파일명에 해당하는 파일 열기

	//파일이 잘 열렸는지 확인하는 함수
	//file.fail(); // 파일 여는 것에 실패하면 true. 성공하면 false
	if (file.fail()) {
		cout << "파일 없음" << endl;
		return -1; // main함수 종료
	}

	cout << "------파일 있음------" << endl;

	std::string str ;
	//file >> str ; // 파일 내용을 str에 저장. 공백(띄어쓰기, 엔터 등) 전까지만 읽어옴.

	std::string str2;
	//file >> str2; // 공백 이후의 문자열을 file에 저장

	//std::string str, str2;
	//file >> str >> str2;   //이렇게도 가능

	//cout << str << " " << str2;
	
	/* //파일 끝까지 읽어오는 방법
	while (file >> str >> str2) {
		cout << str << " " << str2;
		cout << endl;
	}
	*/


	std::string line;
	// file의 내용을 한 줄씩("\n") 불러와 원형을 그대로 불러와 line에 저장하는 방법
	// std::getline(file, line);

	while (std::getline(file, line)) {
		cout << line << endl;
	}	


	//파일 닫는 기능
	file.close();
}

ofstream

  • 프로그램의 출력을 파일에 저장할 수 있게 돕는 클래스
  • 프로그램 -> 파일
std::ofstream file; 
file.open("test_file2.txt");
std::ofstream file("test_file2.txt");

ofstream -파일 쓰기

std::ofstream file("test_file2.txt");
if (file.fail()) cout << "파일 없음" << endl; 
// 보통 쓰기권한에서는 파일이 없을 경우 자동으로 생성됨. 
// 만약 자동으로 생성되지 않았을 경우 fail()이 true가 나올 예정
file << "hello world!"; // hello world라는 글자를 test_file2.txt에 작성
int main() {
	//ifstream: 파일 -> 프로그램
	//ofstream: 프로그램 -> 파일
	//ofstream file();
	//file.open("file_test2.txt");
    
    //파일이 없다면 파일 생성!, ios::trunc = 덮어쓰기, ios::app 추가하기 
	ofstream file("file_test2.txt", ios::out | ios::trunc); 
	if (file.fail()) {
		cout << "파일 없음" << endl;
		return -1;
	}

	file << "hello world!!" << "\n" << "hello C++"; 
	

	file.close();
}

파일 입출력 실습 1

  • file_test의 내용을 file_test2로 옮기기
#include <iostream>
#include <fstream>
#include <string>

// file_test 내용을 file_test2로 옮기기

using namespace std;

bool checkFileOpen(ifstream &file) {
	if (file.fail()) {
		cout << "파일 없음" << endl;
		return false;
	}
	else {
		return true;
	}
}

int main() {
	//파일 변수설정
	ifstream file_r("file_test.txt");
	//함수호출
	if (!checkFileOpen(file_r)) return -1;

	string line, file_content = "";
	while (getline(file_r, line)) {
		file_content += line + "\n";
	}

	cout << file_content;

	ofstream file("file_test2.txt"); 
	if (file.fail()) {
		cout << "파일 없음" << endl;
		return -1;
	}

	file << file_content ;

	file.close();
}

파일 입출력 실습 2

  • 회원 명부 작성하기
  • 사용자에게 3명의 회원에 대한 이름, 비밀번호 입력받기
  • 사용자로부터 입력된 정보를 member.txt에 기록(파일 쓰기모드)
  • member.txt에 저장된 회원 명부 출력(파일 읽기모드)
struct Member {
    string name;
    string password;
};

int main() {
    Member members[3];

    // 사용자에게 3명의 회원에 대한 이름 비밀번호 입력받기
    for (int i = 0; i < 3; i++) {
        cout << i + 1 << "번째 회원의 아이디와 비밀번호를 입력하세요" << ": ";
        cin >> members[i].name >> members[i].password;
    }

    // 사용자로부터 입력된 정보를 member.txt에 기록
    ofstream memberFile("member.txt");
    for (int i = 0; i < 3; i++) {
        memberFile << members[i].name << " " << members[i].password << endl;
    }
    memberFile.close();

    // member.txt에 저장된 회원명부 출력
    cout << "회원 명부:" << endl;
    ifstream inputFile("member.txt");
    while (inputFile >> members[0].name >> members[0].password) {
        cout << members[0].name << " " << members[0].password << endl;
    }
    inputFile.close();

    return 0;
}

파일 입출력 실습 3

  • 회원 명부를 응용한 로그인 기능
  • 사용자에게 "이름을 입력하세요: "메세지를 출력한 뒤 이름 입력 받기
  • 사용자에게 "비밀번호를 입력하세요: "메세지를 출력한 뒤 비번 입력 받기
  • 여기서 member.txt 앞 실습에서 만든 회원 명부
int main() {
    string name, password;

    // 사용자에게 "이름을 입력하세요: "라는 메세지를 출력한 뒤 이름 입력받기
    cout << "이름을 입력하세요: ";
    cin >> name;

    // 사용자에게 "비밀번호를 입력하세요: "라는 메세지를 출력한 뒤 비번 입력 받기
    cout << "비밀번호를 입력하세요: ";
    cin >> password;

    // member.txt. 에서 한 줄씩 "이름"과 "비밀번호"를 검사하여 로그인 성공시 "로그인 성공" 실패시 "로그인 실패" 출력
    string fileName, filePassword;
    ifstream inputFile("member.txt");
    while (inputFile >> fileName >> filePassword) {
        if (name == fileName && password == filePassword) {
            cout << "로그인 성공" << endl;
            return -1;
        }
    }
    cout << "로그인 실패" << endl;
    inputFile.close();

    return 0;
}

파일 입출력 실습 번외

  • 실습 2번에서 로그인 성공 시 회원의 전화번호를 묻고, 회원 전화번호를 파일에 저장하기
ex) 성춘향으로 로그인 성공시
output: "전화번호를 입력해주세요"
input : 010-0000-0000
-> member_tel.txt 파일에 저장.
(추후 다른 사람이 로그인 성공할 경우 누적해서 저장)
[member.txt]
홍길동 134
성춘향 4321
코디 1111
[member_tel.txt]
성춘향 010-0000-0000
  • 할 수 있다면, member_tel.txt의 파일을 분석하여 같은 사람이 로그인 성공하고 전화번호를 입력할 경우, 원래 있던 값을 수정하게끔
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main() {
	string name, password;

	// 사용자에게 "이름을 입력하세요: "라는 메세지를 출력한 뒤 이름 입력받기
	cout << "이름을 입력하세요: ";
	cin >> name;

	// 사용자에게 "비밀번호를 입력하세요: "라는 메세지를 출력한 뒤 비번 입력 받기
	cout << "비밀번호를 입력하세요: ";
	cin >> password;

	// member.txt. 에서 한 줄씩 "이름"과 "비밀번호"를 검사하여,
    // 로그인 성공시 "로그인 성공" 실패시 "로그인 실패" 출력
	string fileName, filePassword;
	ifstream inputFile("member.txt");
	bool is_login = false; //로그인 성공 여부를 저장하는 변수
	while (inputFile >> fileName >> filePassword) {
		if (name == fileName && password == filePassword) {
			is_login = true;
			break;
		}
	}

	inputFile.close();

	if (is_login) {
		cout << "로그인 성공" << endl;

		string InTel, fileTel, member_tel_tmp;
		cout << "전화번호를 입력해 주세요: ";
		cin >> InTel;
		//파일을 읽어 중복 name이 있는지 확인 후 있다면 전화번호만 수정
		ifstream inputTel("member_tel.txt");

		bool is_modify = false; // 수정여부 확인 변수
		if (inputTel.fail()) {
			while (inputTel >> fileName >> fileTel) {
				if (name == fileName) { //이미 파일에 저장된 회원 member_tel_tmp에 저장
					is_modify = true;
					member_tel_tmp += fileName + " " + InTel + "\n";
				}
				else {
					member_tel_tmp += fileName + " " + fileTel + "\n";
				}
			}
		}
		
		//파일 쓰기 -> 회원 이름과 전화번호 저장
		ofstream outputTel;

		//member_tel.txt에 있는 회원 정보 수정
		if (is_modify) {
			outputTel.open("member_tel.txt");
			outputTel << member_tel_tmp;
		}
		//member_tel.txt에 없는 회원의 정보 추가
		else {
			outputTel.open("member_tel.txt", ios::app);
			outputTel << name + " " + InTel + "\n";
		}
		outputTel.close();
	}
	else cout << "로그인 실패";
}


마무리

번외 실습을 완벽하게 해내지 못했었다.
강사님의 도움으로 완성할 수 있었던 자신이 많이 아쉬웠다!
파일 입출력에 대해 강의시간 중에도 이해가 잘 가지 않았는데,
비록 번외 실습을 완성시키진 못 했지만 스스로 해보면서 강의 시간에 이해하지 못했던 부분들을 이해할 수 있게 되어 기분이 썩 나쁘지 않았다.

앞으로 기초적인 C++ 문법은 구조체와 클래스를 빼면 많이 남지 않은 것으로 알고 있다.

강의를 듣다 보면 전부 이해하진 못 하겠지만 최대한 내 것으로 만들기 위해서 스스로 복습도 하고 예습도 하면서 부트 캠프 기간 동안 많은 성장을 이뤄내는 것을 목표로 하고 있다.

목표 잊지 않기를!!
오늘도 수고했고 내일은 더 더 더 파이튕!!

profile
스마트팩토리 개발자가 되기 위한 □□ !!

0개의 댓글