본문 바로가기

C_Data Structure_Algorithm/C telephone v1.0

C 전화번호부 v1.0_2)

1) add 함수


우선, add 명령어의 경우, 아래의 그림과 같이.

2개의 인자값을 줘야 한다

사람 이름

그 사람의 전화번호

다시 2번의 scanf 를 통해

즉, buf1, buf2 를 통해, 사람 이름.과 그 사람의 전화번호.를 받는다.

사람 이름은 buf1, 전화번호를 buf2

names[ n ] = strdup( buf1 )

numbers[ n ] = strdup( buf2 )

각 배열의 n 번째 칸에 저장한다.

왜 n 번째 칸일까 ?

n 이라는 것은, 이미 저장되어있는 사람 수.

처음 n 은 0이다.

배열 index 는 0부터이니까

따라서 만약 5명의 사람이 저장되어 있다면

배열 index 상으로는 0 ~ 4 일 것이다.

그러므로 names[ 5] 를 하게되면, 그 다음 사람을 추가하는 개념이 되는 것이다.

그 이후 n++ 를 통해, 그 다음 사람을 입력할 수 있게 해주는 것이다.

Q. 그런데 왜 strdup 로 해주는 것일까? strcpy 가 아니라.


char *s 를 통해, 문자열을 입력받는다.

문자열. 이란, 문자들의 '배열'이다.

p 라는 배열을 하나 만든 다음에

s 에 있던, sky 라는 문자열을 새로운 배열 p 에 복사하고

p 의 시작 주소를 리턴해주는 역할.

strlen( s ) + 1 : 원래 배열 길이 + 1 ( NULL )

C 언어 에서 문자열을 다룰 때, 뒤에 NULL 을 추가하는 것은 기본.

자. 그렇다면 다시 돌아와서, 왜

names[n] = strdup( buf1 )

이와 같이 해야 하는 거야 ??

봐봐

여기서, buf1과 buf2 는 지역변수들이야.

즉, 얘네는 add 라는 함수가 호출되는 순간 실행이 되고, add 라는 함수가 사라지면, 같이 사라져.

따라서, scanf 를 통해 사용자가 입력한 John 이라는 이름이 buf1 에 저장된다.

그런데 이 buf1 에 저장된 애를 복사하여 넣는 것이 아니라,

직접 그대로 names[n] 에 넣는다면 ( 실제 문법적으로도 가능하지는 않지만 )

함수가 종료되는 순간, buf1, buf2 라는 배열은 사라지고

buf1, buf2 안에 사용자가 입력한 이름과 전화번호도 사라질 것이다.

그런데 names, number 는 전역 변수이다.

항상 유지되는 data 인 것이다.

그래서 buf1 을, strdup 를 통해, 복사를 해서, 그 다음 names 혹은 numbers 에 넣게 되는 것.

즉, strdup 함수를 실행하게 되면, 그 안에서 malloc 을 통해, tmp 라는 새로운 공간을 할당하고, 거기에 john 이라는 문자열을 그대로 복사하고, strdup 가 리턴해주는 주소를 tmp. 에 저장하고, 그 주소를 또 names 에 저장해야.

add 함수가 호출되었다가 종료되어도, names 에 문자열을 넣을 수 있는 것이다.

2) Find


전화번호부에 저장되어 있는 이름들과, 방금 입력된 내용간의 비교( strcmp ) 를 하는 것.

만약에 찾으면, 그 사람의 전화번호부를 화면에 출력하고,

그런 이름을 가진 사람이 없으면, 그런 사람은 없다 ! 라는 메시지 출력하기.

for 문은, 처음부터 마지막 전화번호부 정보를 쭉 훓는 것이다.

strcmp 같은 경우, 두 문자열이 동일하면 0 을 반환하고, 동일하지 않으면 1을 반환한다.

결과가 0 이면, 같다는 의미이므로, i 번째 사람이 내가 찾는 사람이므로, 그 사람의 전화번호부를 출력한다.

3) Status


현재 저장된 사람들과, 전화번호부 들의 목록을 출력하는 것이다.

4) Remove


입력받은 사람을 전화번호부에서 찾아서, 그런 이름을 가진 사람이 있으면, 삭제하고, 없으면 그런 사람이 없다고 출력하기

우선, find 와 같이, 현재 있는 사람들의 이름이 내가 찾으려는 사람과 동일한지를 찾아야 한다.

삭제. 는 어떻게 하는 것일까?

배열 index[i] 에 있는 사람이, 내가 삭제할 사람이다.

이 사람을 삭제하고, 이 자리를 빈칸으로 비워두면 , 프로그램 다른 부분에서 문제가 생긴다.

ex. find 함수에서

for ( i = 0 ; i < n ; i ++ ) { if ( strcmp ( buf , names[ i ] == 0 ) { printf( "%s\n" , numbers[ i ] ) ; return ; } }

같은 경우에는 n 까지 연속적으로 값이 저장되어 있다는 가정하에 돌아가는 것.

즉, n 까지, 빈칸 혹은 공백 없이 실제 사람의 정보가 저장되어 있다는 가정하에 코드가 돌아가는 것인데, remove 함수에서 특정 정보를 제거하고, 그 부분을 빈칸으로 놔두게 되면, 이러한 코드들은 돌아가지 않는다.

빈칸을 남겨둘 수 없다면, 제일 쉬운 해결책은. 그 전화번호부 속에서, 그 배열에서 맨 마지막에 있는 사람의 정보를 그 칸으로 넣는 것이다.

왜냐하면, 어차피 배열 속 사람들의 정보에서, 순서는 의미가 없기 때문이다.

현재 n 명이 있기 때문에, 맨 마지막 index 는 n-1 번째 일 것이다.

names [ i ] = names [ n -1 ]

이런 코드를 통해, 맨 마지막에 있는 사람의 정보를 i 번째 사람의 정보로 넣는 것이다.

그리고 현재 사람 수가 한명 줄어들었기 때문에

n — 를 통해 하는 것이다.

for 문 안에 return 이 있다.

즉, 내가 입력한 사람의 정보를 발견하게 된다면 그 함수를 종료하고 return 하라는 것인데, 만일 찾지 못하면 for 문을 빠져나가서

printf( "No person named '%s' exist. \n" , buf ) ;

를 하라는 의미이다.

최종코드


# include<stdio.h>
    
    # define CAPACITY 100
    # define BUFFER_SIZE 100
     
    char *name[CAPACITY]
    	// 배열 정의 할 때 필요한 3가지
    	// 1. 배열의 이름 ex. names
    	// 2. 배열의 크기 ex. CAPACITY
    	// 3. 배열의 type >> 각 칸에 저장되는 data 의 type 이 무엇이냐. 
    	// 각 칸에 저장되는 것은, 사람의 이름 / 전화번호 >> 문자열 
    	// John\0 >> 배열의 ' 주소 ' 를 가리키는 것이다. 그리고 그 '주소'에 가면
    	// 있는 것이, 하나의 '문자' 이다. 
    	
    char *number[CAPACITY]
    int n = 0 ; // 현재 저장된 사람의 수 , 처음에는 0 명, 이후 n++ 해가면서 사람 수 증가시킬 것.
    	
    void add();
    void find();
    void status();
    void remove(); 
    	
    int main(){
    	
    	// 우리가 일반적으로, 동일한 데이터가 여러 개 있을 때, 그 데이터를 저장하는 가장 기본적인
    	// 자료 구조는 '' 배열 '' 이다.
    	
    	char command[ BUFFER_SIZE ];
    	
    	while(1){
    		
    		printf("$ ");
    		scanf("%s", command);
    		
    		// while 문 안에서 명령어를 하나 받고 다시 올라와라
    		// scanf 로 사용자 명령 입력받아서, 그것을 command 라는 배열에 저장한다.
    		
    		if( strcmp( command, "add" == 0 ) ) 
    			add();
    			// strcmp는 문자열을 비교하는 함수이고,
    			// 그 안에는 우리가 비교할 2개의 문자열을 넣는다.
    			// command 는 우리가 넣는 문자열
    			// add 는, 우리가 비교하고 싶은 문자열이다.
    			// 이 2개의 문자열이 동일하면, 0을 반환한다.  
    		else if( strcmp( command, "find") == 0 )
    			find();
    		
    		else if( strcmp( command, "status") == 0 )
    			status();
    		
    		else if( strcmp( command, "delete") == 0 )
    			remove();
    		else if( strcmp( command, "exit") == 0) 
    			break; 
    	}
    
    	 
    	return 0;
    }
    
    void add(){
    	
    	char buf1[BUFFER_SIZE] , buf2[BUFFER_SIZE];
    	
    	scanf("%s", buf1);
    	scanf("%s", buf2);
    	
    	names[n]   = strdup( buf1 ) ;
    	numbers[n] = strdup( buf2 ) ;
    	n++;
    	
    	printf("%s was added successfully\n", buf1);l
    	
    }
    
    void find(){
    	
    	char buf[BUFFER_SIZE];
    	scanf("%s", buf);
    	
    	int i = 0 ; 
    	for ( i = 0 ; i < n ; i++ ){
    		if( strcmp( buf, names[i] == 0 ) {
    			// strcmp 의 경우, 두 문자열이 동일하면 0 반환, 동일하지 않으면 1 반환  
    			printf("%s\n", numbers[i]);
    			return ;
    		})
    	}
    }
    
    void status(){
    	
    	int i ;
    	for( i = 0; i < n ; i++ ){
    		printf("%s %s\n", nanmes[i], numbers[i]);
    	} 
    	printf("Total %d persons\n", n);
    }
    
    void remove(){
    	char buf[BUFFER_SIZE];
    	scanf("%s", buf);
    	
    	int i ;
    	for( i = 0 ; i< n ; i++){
    		if( strcmp( buf, names[i] == 0) ){
    			names[i] = names[n-1];
    			numbers[i] = numbers[n-1];
    			n--;
    			printf("%s was deleted successfully\n", buf);
    			return ;
    		}
    	}
    	// for 문을 나왔다는 것은, 일치하는 사람이 없다는 것.  
    	printf("No person named '%s' exists \n", buf);
    }

 

'C_Data Structure_Algorithm > C telephone v1.0' 카테고리의 다른 글

C 전화번호부 v1.0_1)  (0) 2020.02.28