2011-1 학기프로그래밍입문 (1) chapter 06-4 참고자료 문자열의처리 박종혁 Tel: 970-6702 Email: jhpark1@seoultech.ac.kr h k 한빛미디어 출처 : 뇌를자극하는 C프로그래밍, 한빛미디어 -1- ehanbit.net
문자열의연산 문자열은배열의형태로구현된응용자료형이므로연산을자유롭게할수없다. 배열에저장된문자열의길이를계산하는작업도간단하지않다. char str[80]= dream ; 배열의길이는전체 80바이트 int count=0; int i=0; d r e a m 0??? while(str[i]!= 0 ){ count++; i++; 문자열의길이는 5바이트! printf( 배열에저장된문자열의길이 : %d n, count); 문자열의연산에는문자열복사, 길이계산, 대소비교, 문자열붙이 기등이있다. 한빛미디어 -2- ehanbit.net
문자열상수는포인터다! 프로그램에서사용된모든문자열은메모리에배열의형태로저장된다. 문자열이컴파일되면첫번째문자를가리키는포인터로치환된다. 결국문자열상수는 char 형을가리키는포인터이다! #include <stdio.h> int main() { printf(" 주소값을출력 : %u n", "dream"); 주소값을출력 : 4350068 printf(" 첫번째문자를출력 : %c n", *"dream"); 첫번째문자를출력 : d printf(" 세번째문자를출력 : %c n", "dream"[2]); 세번재문자를출력 : e return 0; 한빛미디어 -3- ehanbit.net
포인터변수로문자열처리하기 문자열상수가포인터이므로포인터변수에저장하여사용할수있다. printf( 이름 : %s n, name); printf( 여섯번째문자 : %c n, name[5]); 한빛미디어 -4- ehanbit.net
포인터변수로문자열처리하기 문자열상수는상수이므로포인터변수로그값을바꿀수없다. 그러나포인터변수의값은바꿀수있으므로포인터변수가문자열상수의중간을가리키게끔할수있다. #include <stdio.h> int main() { char *fruit="strawberry"; while(*fruit!= ' 0'){ printf("%s n", " fruit); fruit++; return 0; 한빛미디어 -5- ehanbit.net
포인터변수로문자열처리하기 포인터변수는여러개의문자열을선택하여처리할수있다. #include <stdio.h> int main() { int age; char *greeting; printf( 나이를입력하세요 : ); scanf( %d, &age); if(age>30) greeting= 처음뵙겠습니다. ; else greeting= 반가워요. ; // 나이에따라서로다른문자열을저장한다. printf( 인사말 : %s n, greeting); return 0; 한빛미디어 -6- ehanbit.net
문자열상수의두얼굴 문자열상수를포인터변수에초기화하는것과배열에초기화하는것은서로다른의미를가진다. char *fruit = strawberry ; char fruit[20] = strawberry ; // 포인터변수에포인터를초기화한다. // 배열에문자열상수의데이터를복사한다. 배열에문자열상수로초기화하는것은특별한경우로선언과동시에초기화할때만가능하다. 상수를상수에대입하는것이므로불가능하다!! 한빛미디어 -7- ehanbit.net
문자배열에문자열상수를저장하려면? 문자배열에문자열상수를저장하려면문자열상수의문자들을직접하나씩배열에복사해야한다. 문자열을복사하는함수를만들어보자. 한빛미디어 -8- ehanbit.net
함수로문자열을복사하는프로그램 #include <stdio.h> void user_strcpy(char *, char *); int main() { char fruit[20]; user_strcpy(fruit, strawberry ); printf( 배열에저장된문자열 : %s n, fruit); return 0; void user_strcpy(char *des, char *src) { while(*src!= 0 ){ *des = *src; src++; des++; *des= 0 ; // fruit = strawberry ; 와같이사용할수없으므로 // 함수를만들어문자열을일일이배열에복사한다. 한빛미디어 -9- ehanbit.net
중요한문자열처리함수 문자열을처리하는함수는라이브러리로컴파일러와함께제공된다. 문자열처리함수를사용할때는 string.h 헤더파일을 include 한다. 문자열복사함수 : strcpy(string copy) 문자열의길이계산함수 : strlen(string length) 문자열비교함수 : strcmp(string compare) 두개의문자열을붙이는함수 : strcat(string concatenation) 한빛미디어 -10- ehanbit.net
문자열복사함수 (strcpy) 문자열상수나배열에저장된문자열을다른배열에복사한다. - 두번째전달인자로주어지는문자열을첫번째전달인자의위치에복사한다. 두배열에저장된문자열을바꾸는프로그램 #include <stdio.h> #include <string.h> // 헤더파일포함 int main() { char str1[20]= apple ; char str2[20]= banana ; char temp[20]; strcpy(temp, str1); // apple -> temp strcpy(str1, str2); // banana -> >str1 strcpy(str2, temp); // apple -> str2 printf( str1 : %s n, str1); printf( str2 : %s n, str2); return 0; 한빛미디어 -11- ehanbit.net
문자열의길이를계산하는함수 (strlen) 문자열상수나배열에저장된문자열을다른배열에복사한다. - 전달인자로주어지는문자열의길이를계산하여리턴한다 ( 널문자제외 ). char fruit[80] = apple ; int len; len = strlen(fruit); printf( 문자열의길이 :%d n, len); // 문자열의길이 :5 배열에저장된문자열의길이만을계산해준다. 문자열상수나문자열을가리키는포인터변수를사용할수도있다. char *strp = apple ; strlen(strp); strlen( banana ); 한빛미디어 -12- ehanbit.net
문자열을비교하는함수 (strcmp) 두문자열의사전적순서를따진다. - 두문자열을비교하여리턴하는값 ( 사전의뒤에나오는것이큰문자열이다 ). 크기비교 str1 > str2 str1 < str2 str1 == str2 리턴값 1-1 0 두문자열의순서를따져서사전순서로바꾸는예 #include <stdio.h> #include <string.h> int main() { char str1[20]= banana ; char str2[20]= apple ; char temp[20]; int res; return 0; res=strcmp(str1, str2); if(res>0){ // str1이더크면문자열을바꾼다. strcpy(temp, str1); strcpy(str1, str2); strcpy(str2, temp); printf( str1 : %s n, str1); printf( str2 : %s n, str2); 한빛미디어 -13- ehanbit.net
두개의문자열을붙이는함수 (strcat) 두문자열을붙여서하나의문자열을만든다. - str2 의문자열을 str1 의문자열뒤에붙인다. #include <stdio.h> #include <string.h> int main() { char fruit[80]= straw ; strcat(fruit, berry ); printf( 연결된문자열 : %s n, fruit); return 0; 한빛미디어 -14- ehanbit.net
문자열의입출력 scanf 함수는빈칸이포함된문자열은입력할수없다. char str[80]; printf( 문자열을입력하세요 : ); scanf( %s, str); printf( 입력된문자열 : %s n, str); 문자열을입력하세요 : 백번보는것보다한번짜보는것이낫다. ( 엔터 ) 입력된문자열 : 백번 // 첫번재빈칸이후의문자열은입력되지않았다. 문자열의입출력은전용함수를사용한다. 한줄을모두입력하는함수 (gets) 문자열을출력하는함수 (puts) 한빛미디어 -15- ehanbit.net
한줄을모두입력하는함수 (gets) gets 함수는빈칸을포함하여한줄을입력할수있다. - 전달인자는입력받을배열의주소이다. - 입력될문자열이충분히저장될수있도록배열을선언해야한다. - 데이터를입력한후에마지막에널문자를붙여서문자열을완성한다. char str[80]; printf( 문자열을입력하세요 : ); gets(str); printf( 입력된문자열 : %s n, str); 문자열을입력하세요 : 백번보는것보다한번짜보는것이낫다. ( 엔터 ) 입력된문자열 : 백번보는것보다한번짜보는것이낫다. 한빛미디어 -16- ehanbit.net
문자열을출력하는함수 (puts) puts 함수는문자열만을출력하는전용함수이다. - 문자열만을출력하므로 printf 함수보다훨씬작고간편하다. - 출력할문자열이저장된배열명을전달인자로준다. - 문자열을출력한후에는자동으로줄이바뀐다. char str[80]; printf( 문자열을입력하세요 : ); gets(str); printf( 입력된문자열 : ); puts(str) // printf( %s n, str); 문자열을입력하세요 : 백번보는것보다한번짜보는것이낫다. ( 엔터 ) 입력된문자열 : 백번보는것보다한번짜보는것이낫다. // 커서의위치! 한빛미디어 -17- ehanbit.net
소설이어쓰기프로그램 ( 문자열처리함수사용예 ) 키보드로하나의문장들을입력받을때마다이미입력받은문장들과연결하여전체를출력한다. 끝 이입력되면프로그램을종료한다. 문자열을입력하세요 : 문자열은 ( 엔터 ) 현재까지의줄거리 : 문자열은 문자열을입력하세요 : 컴파일되면 ( 엔터 ) 현재까지의줄거리 : 문자열은컴파일되면 문자열을입력하세요 : 주소를 ( 엔터 ) 현재까지의줄거리 : 문자열은컴파일되면주소를 문자열을입력하세요 : 남긴다 ( 엔터 ) 현재까지의줄거리 : 문자열은컴파일되면주소를남긴다. 문자열을입력하세요 : 끝 ( 엔터 ) // 프로그램종료 한빛미디어 -18- ehanbit.net
소설이어쓰기프로그램 ( 문자열처리함수사용예 ) #include <stdio.h> #include <string.h> int main() { char novel[800]={0; char str_in[80]; while(1){ printf(" 문자열을입력하세요 : "); gets(str_in); if(strcmp(str_in, " 끝 ")==0) break; strcat(novel, str_in); strcat(novel, ""); printf(" 현재까지의줄거리 : "); puts(novel); puts(" n"); return 0; // 전체줄거리를저장할배열, 초기화가필요하다! // 입력문자열을저장할배열 // 한줄을입력한다. // 입력된문자열이 끝 이면반복문을빠져나간다. // 입력된문자열을전체줄거리에붙인다. // 다음문자열을위해한칸띄운다. // 전체줄거리출력 // 한줄을띄운다. // novel 배열을널문자로초기화하지않으면쓰레기문자들이있으므로 // 처음에문자열붙일때쓰레기문자들이남을가능성이있다!! 한빛미디어 -19- ehanbit.net
문자입출력함수 하나의문자만을전용으로입출력하는함수들이있다. 문자들을연속으로입출력하면문자열의입출력이된다. 문자입력함수 : getchar 문자출력함수 : putchar 한빛미디어 -20- ehanbit.net
하나의문자를입출력하자. 하나의문자를입출력할때는문자전용입출력함수를사용하는것이효율적이다. - getchar함수는키보드로부터문자를입력받아서리턴한다. - putchar함수는전달인자로주어지는문자를화면에출력한다. - 두함수모두 stdio.h 헤더파일을 include 하면사용할수있다. #include <stdio.h> int main() { int ch; printf( 문자하나를입력하세요 : ); ch=getchar(); printf( 입력된문자 : ); putchar(ch); return 0; 한빛미디어 -21- ehanbit.net
문자열을입출력하자. 하나의문자를반복적으로입출력하면문자열의입출력이된다. - 문자열을입력할때는마지막에반드시널문자를채워준다. - 배열에 Love 문자열을입력하는예 #include <stdio.h> int main() { char str[80]; int ch; int i; printf( 문자열을입력하세요 : ); for(i=0; i<4; i++){ ch=getchar(); str[i]=ch; str[i]= 0 ; printf( 입력된문자열 : ); i=0; while(str[i]= 0 ){ putchar(str[i]); i++; return 0; // 문자열을저장할배열 // getchar함수의리턴값을저장할변수 // 반복제어변수 // i는 0부터 3까지변하면선 4번반복 // 키보드로부터문자를입력받아리턴한다. // 리턴된문자를배열에차례로저장 // 마지막에널문자를저장하여문자열을완성한다. // 제어변수를다시 0 으로초기화 // 배열요소가널문자가아닌동안반복 // 화면에문자출력 // 다음문자로이동 한빛미디어 -22- ehanbit.net
데이터의입력은버퍼를사용한다. 키보드에서입력되는데이터는일단버퍼에저장되고 getchar함수는버퍼로부터데이터를가져오므로문자열은한번에입력한다. 문자열을입력하세요 : Love ( 엔터 ) 입력된문자열 : Love 문자를하나씩입력하면새줄문자로입력되므로문제가발생한다. 문자열을입력하세요 : L ( 엔터 ) o ( 엔터 ) // 두번째문자를입력할때입력이끝난다. 입력된문자열 : L o 한빛미디어 -23- ehanbit.net
한줄을입력하자. getchar 함수가새줄문자 ( n ) 도하나의문자로입력하므로이 문자를이용하여한줄을입력받을수있다. printf( 문자열을입력하세요 : ); while(1){ // 무한반복 ch=getchar(); // 퍼버로부터문자하나를입력한다. if(ch== n ) break; // 그문자가새줄문자이면입력종료 str[i]=ch; // 배열요소에입력한문자를저장 i++; // 다음배열요소로이동 str[i]= 0 ; // 마지막에널문자를넣어문자열을완성한다. 키보드입력 스트림버퍼 Love ( 엔터 ) L o v e n 한빛미디어 -24- ehanbit.net
여러줄을입력하자. 새줄문자도하나의문자로입력하면여러줄을하나의문자열로 입력할수있다. 입력의종료는 Ctrl + Z 키를누른다. - getchar함수는키보드에서 Ctrl + Z키가눌려지면 -1을리턴하므로이값을비교하여입력을종료할수있다. printf( 문자열을입력하세요 : ); while(1){ ch=getchar(); if(ch==-1) break; str[i]=ch; i++; str[i]= 0 ; printf( 입력된문자열 : ); puts(str); // getchar 함수가 -1 을리턴하면입력을종료한다. 문자열을입력하세요 : 10분더공부하면 ( 엔터 ) 배우자의직업이바뀐다. ( 엔터 ) ^Z ( 엔터 ) 입력된문자열 : 10분더공부하면배우자의직업이바뀐다. 한빛미디어 -25- ehanbit.net