게임 저장할 함수들 사용을 편하게 하기 위해서 다른 파일에 존재하는 저장할 변수들을 extern을 이용하여 불러왔다. 파일을 저장할떄 1을 먼저넣음으로써 내용이 저장되어있음을 알리고 파일을 삭제하는 것 대신 저장한내용들을 없애는것을 표기하기 위해 저장할때 숫자 0을 먼저 넣어주었다..
game.h에서 열거형 enum을 사용하여 각 가위 바위 보를 1 ,2 ,3에 대응 시켰다.
WhoIsWinner를 처음에는 모든 경우에 case들을 분류했었는데 훨씬 간편하게 고친것 같다.
위와같이 w옵션을 주어 fopen함수 사용시 파일명에 해당하는 파일이 없다면 새로 생성하여 안에 데이터를 입력한다.
소스파일에서 설명했듯이 리눅스에서 한글은 2~3바이트로 불규칙 적이다. 실행화면을 보면 2개의 문자를 요청했으며 하나는 정상적으로 출력이 완료되었지만 다른 하나는 비정상적인 출력이 되는것을 알 수 있다.이것은 출력하려는 데이터의 크기가 정확하지 않아서 발생하는 문제이다.
fopen함수에서 wb옵션을 준것은 바이너리 모드로 열어서 쓰겠다는 의미이다. 바이너리 모드란 숫자 4를 넣을때 아스키코드값이 들어가는 것이아니라 이진데이터 4가 들어가는 것을 의미합니다. 저장된 파일을 열어보면 알수 없는 형태로 저장되는것을 확인할 수 있습니다.
rb는 바이너리모드로 열어서 읽는 다는 옵션이다.
바이너리 모드로 열어서 저장한데이터는 바이너리모드로 열어서 읽으면 저장한 그대로 출력이 가능하다.
위 소스코드로 입력한 결과이다. wt는 텍스트 모드로 열어서 쓴다는 의미이다. 데이터를 아스키코드값으로 저장한다.
날짜는 바이너리모드로 입력하고 다른 데이터들은 텍스트 모드로 입력하는 파일이다.
바이너리 모드로 된 데이터는 바이너리모드로 읽고 텍스트모드로 저장된 데이터는 텍스트 모드로 읽으면된다.
날짜와 지역 오전오후만 입력해서 해당 데이터를 출력하는 것이다. 검색하는 데이터만 읽어야한다고 생각을 해서 문제해결에 어려움이 있었다. 그냥 데이터를 다읽어서 입력한 데이터와 비교하여 같은 부분만 출력하는 형태로 문제를 풀었다.
파일을 바이너리모드로 열고 텍스트 문자를 입력하고 바이너리모드로 열어서 데이터를 읽는 것이다. 문자열을 읽어서 출력하는 부분에서 fgets를 사용하면 편했겠지만 문제에서 요구하는것은 fread를 사용하는 것이다. fread를 사용할때는 개행문자('\n')까지만 읽는것이 아니라서 해당 문자열일때 break를 걸어주는 방식으로 문제를 풀었다.
파일을 복사하는 프로그램이다. 파일이름을 가져올때는 fgets를 사용해서는 안된다. 개행문자('\n')까지 파일명으로 인식하기 때문이다.
파일데이터를 복사할 때는 바이너리모드로 여는것이 좋을 듯 하다. 텍스트 모드로 파일을 열면 '\n'가 '\r\n'으로 변경되기 때문이다.
fgetc는 한글자씩 읽기 때문에 해당 프로그램의 성능은 좋지 않다.
fread와 fwrite를 통해 데이터를 복사하는 프로그램이다. feof함수는 파일의 끝을 알려주는 함수가아니라, 더이상 읽을 데이터가 없는데도 읽을려고 할때 feof는 0이아닌값을 반환한다. 즉 파일을 읽는 함수인 fread이후에 배치되어야한다.
각 파일들에 같은 구조체로 각각 선언되어있다. 이러한 이유는 C파일을 object파일로 컴파일 할때 컴파일러는 각 파일단위로 각각 컴파일을 진행하기 때문이다. 한 파일에 선언된 구조체를 다른파일에서 사용할 수 없다. 각 파일들을 오브젝트 파일로 컴파일하고 이러한 오브젝트 파일들은 링커에 의해 연결된다.
각 오브젝트 파일을 하나로 묶어서 실행파일을 생성하는 것은 링커가 진행하는데 이때 링커는 main함수를 찾아 실행파일을 만들 방법을 찾는다. main함수 없이는 실행 파일을 만들 수 없다. main함수가 프로그램의 시작위치를 알려준다.
main함수를 찾고나서 각각 전역변수의 접근과 함수의 호출 관계를 파악한다. 이러한 과정을 통해 링커는 여러 오브젝트 파일을 묶어 실행파일을 생성해 낸다.
링커가 하는 일은 하나이상의 오브젝트 파일을 묶어서 하나의 실행파일을 만드는 일을 한다.
각 헤더파일에 ifndef 을 사용한것은 중복 정의를 피하기 위해 정의한 것이다. ifndef은 if not define 의 약자로 point.h의 경우 __POINT_H__가 정의되어있지 않으면 __POINT_H__를 정의하고 해당 구조체를 정의하는 것이다. 이후에 개발자의 실수로 point.h를 두번 선언하게 되더라도 중복을 피할 수 있도록 정의한 것이다.
pointOperation.h에도 point.h가 선언되어있다. main.c에는 pointOperation.h와 point.h가 각각 선언되어있어 결과적으로 point.h가 두번 선언되어있는데 ifndef을 통해 중복을 막을 수 있다. 그리고 point.h의 구조체의 선언같은 경우 중복되면 컴파일 에러가 발생할 수 있어 ifndef의 중요성을 인식할 수 있다. 개발시 실수를 방지하기 위해 해더파일에 ifndef을 꼭 추가해주는 것이 좋을 듯 하다.
하나의 헤더파일에 여러 함수들을 선언하고 4개의 함수들을 2개의 파일에 걸쳐 정의하였다.
main함수에서는 myString.h만 include해주면 컴파일 에러가 발생하지않으니 간편하것 같다.