두 개의 텍스트 파일이 같은지 다른지를 확인하는 프로그램을 작성해 보자.
단순히 공백문자 하나가 차이를 보여도 두 텍스트 파일은 다른 것으로 판별이 나야 한다.
# 실행의 예
/*다음은 실행파일의 이름이 comp.exe 이고, 비교의 대상이 되는
두 파일의 이름이 각각 d1.txt 와 d2.txt인 경우의 실행의 예이다.*/
C:\test>comp d1.txt d2.txt
두 개의 파일은 완전히 일치 합니다.
헤더 파일 포함하기
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
- #define _CRT_SECURE_NO_WARNINGS
- scanf_s 등을 사용하고 싶지 않을 때 컴파일러가 보안 관련 경고를 발생시키지 않도록 할 수 있다.
- #include <stdio.h>
- 표준 입출력 함수를 사용하기 위해 필요한 헤더 파일이다
- printf, fgets, fopen, fclose, scanf 등의 함수가 여기에 정의되어 있다.
- #include <string.h>
- 문자열 처리 함수를 사용하기 위한 헤더 파일이다.
- 이 예제에서는 strcmp 함수를 사용하여 두 문자열이 같은지를 비교한다.
상수 정의하기
const int SAME=1;
const int DIFF=2;
- SAME과 DIFF는 프로그램 내에서 파일 비교 결과를 나타내는 상수이다. SAME은 두 파일이 같음을, DIFF는 두 파일이 다름을 나타낸다.
Main 함수
int main(int argc, char *argv[])
- argc는 커맨드 라인에서 입력된 인자의 몇 개인지 세고 argv는 인자의 값들이 뭔지 보여주는 문자열 배열의 포인터이다.
변수 선언하기
FILE *sorc1;
FILE *sorc2;
char str1[100], str2[100];
int state1, state2;
int flag=SAME; // same or diff
- sorc1과 sorc2는 FILE 타입의 포인터 변수로, 두 개의 파일을 각각 가리키기 위해 사용된다. fopen 함수를 통해 이 변수들에 파일 스트림을 할당하고, 이후 fgets 등의 함수를 사용해 파일의 내용을 읽거나 처리할 수 있다.
- str1과 str2는 각각 100개의 문자를 저장할 수 있는 문자 배열이다. 이 배열들은 sorc1과 sorc2에서 읽은 각 파일의 한 줄씩을 저장하는 데 사용된다. fgets 함수를 이용해 파일로부터 문자열을 읽어들일 때 이 배열들이 사용된다.
- state1과 state2는 파일을 닫을 때 fclose 함수의 반환 값을 저장하기 위한 변수이다. fclose 함수는 성공적으로 파일을 닫았을 때 0을 반환하고, 실패했을 때 0이 아닌 값을 반환한다. 이 변수들을 통해 각 파일이 제대로 닫혔는지 여부를 확인할 수 있다.
- flag는 두 파일의 비교 결과를 나타내는 변수이다. 초기값으로 SAME을 할당하여, 두 파일이 같다고 가정한다. 파일을 비교하는 과정 중에 두 파일의 내용이 다른 부분이 발견되면, 이 변수의 값을 DIFF로 변경한다. 프로그램의 마지막 부분에서 이 변수를 검사하여 두 파일이 같은지 다른지에 대한 결과를 사용자에게 알린다.
인자 검사하기
if(argc!=3)
{
puts("usage : comp source1 source2 \n");
return 1;
}
- 프로그램은 정확히 두 개의 파일 이름을 인자로 받아야 한다. argc가 3이 아니면(프로그램 이름 포함이므로), 사용 방법을 안내하는 메시지를 출력하고, 1을 반환하여 오류와 함께 프로그램을 종료한다.
파일 열기
sorc1=fopen(argv[1], "rt");
sorc2=fopen(argv[2], "rt");
- fopen 함수를 사용하여 두 파일을 텍스트 읽기 모드("rt")로 연다.
- argv[1]과 argv[2]는 사용자가 입력한 두 파일의 경로이다.
파일 열기 오류 검사
if(sorc1==NULL || sorc2==NULL)
{
printf("file open error!\n");
return 1;
}
- 두 파일 중 하나라도 열기에 실패하면 오류 메시지를 출력하고, 프로그램을 종료한다.
파일 내용 비교
while(1)
{
if(feof(sorc1)!=0 && feof(sorc2)!=0)
break;
fgets(str1, sizeof(str1), sorc1);
fgets(str2, sizeof(str2), sorc2);
if(strcmp(str1, str2)!=0)
{
flag=DIFF;
break;
}
}
- feof() 함수는 파일의 끝(EOF, End Of File)에 도달했는지를 확인하는 함수이다. 파일의 끝에 도달했을 때 feof() 함수는 0이 아닌 값을 반환한다. 파일의 끝이 아니면 0을 반환한다. 여기서는 파일 2개 모두 파일의 끝에 도달하면 반복문을 빠져나온다.
- 무한 루프 내에서 두 파일의 내용을 한 줄씩 읽어서 비교한다. fgets 함수로 각 파일에서 한 줄씩 읽는다.
- strcmp 함수로 두 문자열이 같은지 비교한다. 문자열이 다르면 flag를 DIFF로 설정하고 루프를 빠져나온다.
비교 결과 출력
if(flag==SAME)
fputs("두 개의 파일은 완전히 일치 합니다.", stdout);
else
fputs("두 개의 파일은 불일치 합니다.", stdout);
- flag의 값에 따라 두 파일이 같은지 다른지에 대한 메시지를 출력합니다.
파일 닫기
state1=fclose(sorc1);
state2=fclose(sorc2);
- 열린 파일을 닫는다.
프로그램 종료
if(state1!=0||state2!=0)
{
printf("file close error!\n");
return 1;
}
return 0;
- 파일을 닫는 데 실패했다면 오류 메시지를 출력하고, 오류와 함께 프로그램을 종료한다. 그렇지 않다면 성공적으로 프로그램을 종료한다. (0을 반환).
완성된 코드문
#include <stdio.h>
#include <string.h>
const int SAME=1;
const int DIFF=2;
int main(int argc, char *argv[])
{
FILE *sorc1;
FILE *sorc2;
char str1[100], str2[100];
int state1, state2;
int flag=SAME; // same or diff
if(argc!=3)
{
puts("usage : comp sorurce1 source2 \n");
return 1;
}
/* 파일의 개방 */
sorc1=fopen(argv[1], "rt");
sorc2=fopen(argv[2], "rt");
if(sorc1==NULL || sorc2==NULL)
{
printf("file open error!\n");
return 1;
}
/* FILE COMPARE */
while(1)
{
if(feof(sorc1)!=0 && feof(sorc2)!=0)
break;
fgets(str1, sizeof(str1), sorc1);
fgets(str2, sizeof(str2), sorc2);
if(strcmp(str1, str2)!=0)
{
flag=DIFF;
break;
}
}
if(flag==SAME)
fputs("두 개의 파일은 완전히 일치 합니다.", stdout);
else
fputs("두 개의 파일은 불일치 합니다.", stdout);
/* 파일의 종결 */
state1=fclose(sorc1);
state2=fclose(sorc2);
if(state1!=0||state2!=0)
{
printf("file close error!\n");
return 1;
}
return 0;
}
'윤성우의 C Programming' 카테고리의 다른 글
Chapter 12. 포인터의 이해 (0) | 2024.02.28 |
---|---|
Chapter 13. 포인터와 배열 (0) | 2024.02.27 |
A와 P로 시작하는 단어의 수를 세어서 출력하기 (1) | 2024.02.13 |
Chapter 27. 파일의 분할과 헤더파일의 디자인 (0) | 2024.02.12 |
Chapter 26. 매크로와 선행처리기 (Preprocessor) (1) | 2024.02.12 |