문제해결기법 두 번째 레포트입니다. 이번 것은 예제의 것을 직접 해보는 정도의 수준이었습니다. 시험에 나온다는 뜻?!

  1: #include <stdio.h>
  2: #include <stdlib.h>
  3: #include <string.h>
  4: 
  5: #define MAXLEN 1001		// 문자열 최대 길이
  6: #define MAXCHANGES 101	// 바꾸기 최대 개수
  7: 
  8: typedef char string[MAXLEN];	// 문자열 타입 선언
  9: 
 10: string mergers[MAXCHANGES][2];	// 원본과 수정본을 저장할 수 있는 공간
 11: int nmergers;					// 실제로 바꾸는 횟수
 12: 
 13: // function declaration
 14: void read_changes(FILE* pFile);
 15: void read_quoted_string(char* s, FILE* pFile);
 16: int findmatch(char* p , char* t);
 17: void replace_x_with_y(char* s, int pos, int xlen, char* y);
 18: 
 19: int main(void)
 20: {
 21: 	string one_line_txt;	// fgets에 쓰일 줄 하나를 가져오는 변수
 22: 	FILE* pFile;			// input.txt 파일을 여는 변수
 23: 	int nlines;				// 바꿔야 할 글의 줄 개수
 24: 	int i, j;				// for문에 쓰일 index 변수
 25: 	int pos;				// 원본을 글에서 찾을 때 위치를 저장하는 변수
 26: 
 27: 	// 파일 읽기
 28: 	pFile = fopen("input.txt", "r");
 29: 	// 파일 읽기가 에러면 에러 문구를 띄우고 종료
 30: 	if(NULL == pFile)
 31: 		perror("Error opening file");
 32: 
 33: 	read_changes(pFile);	// 원본과 수정본을 읽어와서 mergers에 저장함.
 34: 
 35: 	fgets(one_line_txt, MAXLEN, pFile);				// 바꿔야 할 텍스트 줄 개수
 36: 	one_line_txt[strlen(one_line_txt)-1] = '\0';	// 문자열로 만듬.
 37: 	nlines = atoi(one_line_txt);					// 숫자로 변환
 38: 
 39: 	// 텍스트 줄을 하나씩 읽어온다.
 40: 	for(i = 0 ; i < nlines ; i++)
 41: 	{
 42: 		fgets(one_line_txt, MAXLEN, pFile);			// 바꿔야 할 텍스트 줄 개수
 43: 		one_line_txt[strlen(one_line_txt)-1] = '\0';// 문자열로 만듬
 44: 		
 45: 		// 저장된 원본-수정본 정보만큼 살펴본다.
 46: 		for(j = 0 ; j < nmergers ; j++)
 47: 		{
 48: 			// 글에서 원본을 찾으면....
 49: 			while(-1 != (pos = findmatch(mergers[j][0], one_line_txt)))
 50: 			{
 51: 				// 글에서 원본의 위치와 길이를 넘겨 수정본으로 바꾸게 한다.
 52: 				replace_x_with_y(one_line_txt, pos, strlen(mergers[j][0]), mergers[j][1]);
 53: 			}
 54: 		}
 55: 
 56: 		printf("%s\n", one_line_txt);				// 바뀐 결과를 화면에 찍는다.
 57: 	}
 58: 
 59: 	fclose(pFile);	// 파일 닫기
 60: 	return 0;		// 프로그램 종료
 61: }
 62: 
 63: // 변화, 즉, 원본-수정본 읽는 함수. pFile은 정보가 들어있는 파일 포인터
 64: void read_changes(FILE* pFile)
 65: {
 66: 	char one_line_txt[4];	// 개수를 읽을 것이기에 크기를 작게한다.
 67: 	int i;					// for문에 쓰일 index 변수
 68: 
 69: 	fgets(one_line_txt, 4, pFile);				// 바꾸는 것 개수
 70: 	one_line_txt[strlen(one_line_txt)-1] = '\0';// 문자열 만들기
 71: 	nmergers = atoi(one_line_txt);				// 숫자로 바꾼다.
 72: 
 73: 	// 쌍따옴표(") 안에 있는 내용물을 한 줄씩 읽어온다.
 74: 	for(i = 0 ; i < nmergers ; i++)
 75: 	{
 76: 		read_quoted_string(mergers[i][0], pFile);	// 원본
 77: 		read_quoted_string(mergers[i][1], pFile);	// 수정본
 78: 	}
 79: 	fgets(one_line_txt, 4, pFile);	// 다음 행을 읽기 위해서 pointer 위치를 다음 줄로 넘긴다.
 80: }
 81: 
 82: // 쌍따옴표(") 안에 있는 문자열을 s에 저장한다.
 83: void read_quoted_string(char* s, FILE* pFile)
 84: {
 85: 	int i = 0;	// s의 index
 86: 	char c;		// 파일에서 글자 하나를 읽어온 후 임시 저장소
 87: 
 88: 	// 쌍따옴표가 발견될 때까지 계속 읽는다.
 89: 	while('\"' != (c = fgetc(pFile)))
 90: 		;
 91: 	// 하나가 발견되었으면 다음 쌍따옴표가 나올 때까지 s에 복사한다.
 92: 	while('\"' != (c = fgetc(pFile)))
 93: 	{
 94: 		s[i] = c;	// 복사
 95: 		i++;		// 다음 index
 96: 	}
 97: 
 98: 	// 문자열은 끝에 '\0'을 붙여야 한다.
 99: 	s[i] = '\0';
100: }
101: 
102: // p : 패턴, t : 텍스트. t에서 p를 찾는다.
103: int findmatch(char* p , char* t)
104: {
105: 	int i, j;			// for문 변수
106: 	int plen, tlen, tmp;// 자세한 것은 밑에...
107: 
108: 	plen = strlen(p);	// p의 문자열 길이
109: 	tlen = strlen(t);	// t의 문자열 길이
110: 	tmp = tlen - plen;	// 밑에 for문에서 자주 쓰이기에 성능을 위해 따로 저장.
111: 
112: 	// naive method 사용
113: 	for(i = 0 ; i <= tmp ; i++)
114: 	{
115: 		j = 0;
116: 		// 패턴 p와 텍스트 t의 글자 하나가 맞으면 j를 증가
117: 		while((j < plen) && (t[i+j]==p[j]))
118: 			j++;
119: 
120: 		// j가 패턴 길이와 같다면, 즉, 모든 글자가 맞다면...
121: 		if(plen == j)
122: 			return i;	// 텍스트의 위치를 반환
123: 	}
124: 
125: 	return -1;	// 찾지 못하였다면 -1을 반환
126: }
127: 
128: // s의 pos 위치에서 길이 xlen인 문자열을 y로 치환한다.
129: void replace_x_with_y(char* s, int pos, int xlen, char* y)
130: {
131: 	int i;				// for문 변수
132: 	int slen, ylen, ymx;// 밑에 자세한 설명
133: 
134: 	slen = strlen(s);	// 문자열 전체 길이
135: 	ylen = strlen(y);	// 치환할 y의 문자열 길이
136: 	ymx = ylen - xlen;	// 자주 쓰이는 식이라 따로 변수 저장
137: 
138: 	if(ymx <= 0)
139: 	{
140: 		// 기존 문자열(x)의 길이가 더 길기에 xlen 뒷부분을 앞당긴다.
141: 		for(i = (pos+xlen) ; i <= slen ; i++)
142: 			s[i+ymx] = s[i];
143: 	}
144: 	else
145: 	{
146: 		// 기존 문자열(x)의 길이가 더 짧기에 xlen 뒷부분을 뒤로 민다.
147: 		for(i = slen ; i >= (pos+xlen) ; i--)
148: 			s[i+ymx] = s[i];
149: 	}
150: 
151: 	// 해당 문자열 삽입
152: 	for(i = 0 ; i < ylen ; i++)
153: 		s[pos+i] = y[i];
154: }
크리에이티브 커먼즈 라이선스
Creative Commons License

글에 잘못된 점, 다른 점, 부족한 점이 있다면 지적해주세요.
댓글, 트랙백, 메일 모두 고맙습니다.

트랙백 주소 :: http://nosyu.pe.kr/trackback/2160

댓글을 달아 주세요

[로그인][오픈아이디란?]