Transcript Chapter 14

Chapter 15 문자열
문자의 집합체
 문자열의 정의
 일련의 문자
 표기 방법
 문자열 앞 뒤에 인용부호 “”를 이용
 문자열 상수
 문자와 문자열과의 차이
2
문자열의 저장
 문자 배열의 이용
 문자열 상수 “c language”를 저장하는 문자열 배열 c2[]를 선언하
는 문장
 정확한 배열의 크기는 문자열의 길이보다 1이 크기 때문에 배열의 크기를
기술하지 않는 방법
char c2[] = "C language";
 문자열의 마지막 NULL 문자를 포함한 정확히 크기를 기술
char c2[11] = "C language";
3
문자열의 저장
 문자 배열의 이용
 문자의 배열 초기 값 표현으로 대입 방법
 주의할 사항은 문자 배열 마지막에 반드시 직접 NULL 문자를 넣어야 함
char c1[] = {'C', ' ', 'l', 'a', 'n', 'g', 'u', 'a', 'g', 'e', '\0'};
 문자 포인터의 이용
 문자열의 마지막 NULL 문자를 포함한 정확히 크기를 기술 력
char *c4 = "C language";
4
문자열 출력
 문자 배열에서 각 문자를 출력
i = 0;
while(c2[i] != '\0')
printf("%c", c2[i++]);
printf("\n");
 문자 포인터의 주소 값을 변경하면서 각 문자를 출력
i = 0;
while(*(c4 + i) != '\0')
printf("%c", *(c4 + i++));
printf("\n");
5
예제 소스
 String.c
 문자 배열 이름인 c1,
cerr, c2, c3와 문자 포
인터 변수 이름인 c4를
이용하여 문자열을 출
력
6
7
문자 포인터 배열을 이용한
여러 문자열
 처리하려는 문자열의 수 만큼의 문자 포인터 이용
char *pary[ ] = {"AT&t", "AT&t", "Sun", "MS"};
 래기드(ragged) 배열
 각 문자열의 출력
for (i = 0; i < 4; )
printf("%-8s", pary[i++]);
//printf("%-8s", *(pary + i++));
printf("\n");
8
문자 포인터 배열
 각 문자의 주소 값
 문자열을 구성하는 각각의 문자를 출력하려면
 *(*(pary + i) + j)을 변환명세 %c로 출력
 여기서 i는 문자열 첨자 순번이고,
 j는 i에 해당하는 문자열의 문자 첨자 순번
printf("Sun의 u 출력 *(*(pary + 2) + 1) = %c\n", *(*(pary + 2) + 1));
9
문자 2차원 배열을 이용한
여러 문자열
 문자 2차원 배열
 2차원 배열의 열의 크기는 문자열 중에서 가장 긴 문자열의 길이보다 1
크게 지정
 2차원 배열의 행의 크기는 문자열의 개수로 지정
char strary[][5] = {"c", "c++", "java", "c#"};
10
문자 2차원 배열에서 출력
 문자 2차원 배열
char strary[][5] = {"c", "c++", "java", "c#"};
 문자 이차원 배열 strary를 이용하여 각 문자열을 출력하려면 strary[i]
로 변환명세 %s를 이용
for (i = 0; i < 4; )
printf("%-8s", strary[i++]);
//printf("%-8s", *(strary + i++));
printf("\n");
 문자를 출력하려면 strary[i][j]을 변환명세 %c로 출력
printf("C++의 앞 + 출력 strary[1][1] = %c\n",
strary[1][1]);
11
예제 소스
 strarray.c
 문자열 배열을 문자 포인터
배열과 문자 2차원 배열로
저장하고, 필요한 문자열과
문자를 참조하는 프로그램
12
문자열 입출력 함수
 함수 gets()
 문자열을 입력하고, 입력 받은 첫 문자의 주소 값을 반환
 이 함수는 표준입력으로 enter키를 누를 때까지 공백을 포함한 모든 문
자열을 입력
 입력된 문자열에는 enter키는 넣지 않고, 마지막에 문자열을 의미하는
NULL 문자인 \0을 추가
 함수 puts()
 문자열을 출력하고 마지막 newline을 출력하여 한 줄에 문자열을 출력
 일반적으로 0인 정수를 반환하며, 오류가 발생하면 EOF를 반환
 기호 상수 EOF는 헤더파일 stdio.h 파일에 정수 -1로 정의되어 있으며,
파일의 끝(End Of File)이라는 의미
char * gets(char *);
int puts(char *);
13
문자열 입출력 함수
 함수 gets()를 이용한 문자열 입력
 문자열을 입력 받을 적절한 문자 배열 이용
 반환 주소 값을 이용하면 문자별로 참조가 가능
char line[81];
char *ptr;
//gets(line);
ptr = gets(line);
while (*ptr)
putchar(* ptr++);
printf("\n");
 함수 puts()를 이용한 문자열 출력
 출력할 문자열의 첫 주소 값을 인자로 출력
char *str = "객체지향 언어를 하나 써 보세요?";
puts(str);
14
예제 소스
 gets.c
 문자열 입출력
함수 gets()와
puts()를 이용하
여 원하는 문자
열의 입출력을
확인
 함수 gets()로
받은 문자열을
함수 reverse()
의 인자로 호출
하여 입력 받은
문자열을 역순으
로 출력
15
예제 소스
 gets.c
16
파일 입출력 함수의 이용
 함수 fgets()
 두 번째 인자는 입력할 문자의 수이고, 세 번째 인자는 입력될 문자열
의 파일
 문자열을 개행문자까지 읽어 개행문자도 함께 입력 문자열에 저장
 함수 fputs()
 문자열을 그대로 출력
char * fgets(char *, int, FILE *);
int fputs(const char *, FILE *);
 표준 입출력 상수
 stdin, stdout
 여러 줄의 입력 후 출력
while (fgets(line, LINENUM, stdin)) {
fputs(line, stdout);
}
17
예제 소스
 fgets.c
 함수 fgets()와 fputs()를 이용
하여 계속적으로 행을 입력하
여 출력
 같은 방식으로 함수 gets()와
puts() 이용
18
버퍼링에 의한 문자 입출력
 함수 getchar(), putchar()
 라인 버퍼링(line buffering)
 입력된 자료가 버퍼에 저장되고 Enter 키를 만나야 getchar() 함수가 작동
char ch;
printf("문자를 계속 입력하고 Enter를 누르면 >>\n");
while ((ch=getchar()) != 'q')
putchar(ch);
19
버퍼링을 사용하지 않는 문자
입력
 함수 getche()
 버퍼를 이용하지 않고 문자 하나 하나를 바로 처리하는 함수
 헤더파일 conio.h 파일을 첨가
 버퍼를 사용하지 않으므로 문자 하나를 입력하면 바로 함수 getche()를 실행
하고 입력 문자가 ‘q’가 아니면 함수 putchar()에 의하여 문자가 바로 출력
char ch;
printf("\n문자를 누를 때마다 두 번 출력 >>\n");
while ((ch=getche()) != 'q')
putchar(ch);
20
버퍼링을 사용하지 않는 문자
입력
 함수 getch()
 함수 getche()와 마찬가지로 버퍼를 사용하지 않는 입력함수
 헤더파일 conio.h 파일을 첨가
 입력한 문자를 화면에 보이지 않는 특성, 입력한 문자를 출력함수로 출력하
지 않으면 그 문자가 화면에 나타나질 않음
char ch;
printf("\n문자를 누를 때마다 한 번 출력 >>\n");
while ((ch=getch()) != 'q')
putchar(ch);
21
예제 소스
 파일 getch.c
 문자 입력함수 getchar(),
getche(), getch()의 차이를
다음 프로그램을 작성하여
이해
 위 프로그램에서 세 개의
while 문의 입력으로 각각
“getchar()q”, “getche()q”,
“getch()q”를 입력하면 무
엇이 출력될 지 예상
22
문자처리 함수
 관련 함수
 문자처리 함수는 헤더파일 ctype.h를 포함시켜 사용
 검사 함수는 isxxx(char)로, 변환 함수는 toxxx(char)로 명명
 검사 함수는 0(false)과 0이 아닌 정수 값(true)을 반환하며, 변환 함수는 변환
된 문자를 반환
 함수 toxxx()
 함수 toupper(c)는 c가 영문 소문자일 때 영문 대문자로 변환하고, c가 소문자
가 아니라면 원래 c가 반환
 마찬가지로 tolower(c)는 각각 c가 영문 대문자일 때 영문 소문자로 변환하고,
c가 대문자가 아니라면 원래 c가 반환
 함수 _toxxx()
 함수 _tolower(c)와 _toupper(c)는 c 값에 관계없이 소문자와 대문자로 변환
 다음과 같이 매크로로 정의되어 있으므로 영문자가 아닌 문자를 적용하면 원
하지 않는 결과가 나오므로 주의
#define _tolower(_c)
#define _toupper(_c)
( (_c)-'A'+'a' )
( (_c)-'a'+'A' )
23
문자처리 함수
 관련 함수
24
예제 소스
 파일 ctype.c
 헤더파일 ctype.h에 있는 문
자 매크로 함수 중에서
isalnum(), ispunct(), isxdigit()
를 이용하는 프로그램
 다양한 문자의 한 줄을 표준
입력으로 받아 모든 문자에
대하여 위 세 개의 함수를 적
용하여 true, false로 출력
 함수 isalnum()을 조건 삼항
자를 이용하여 출력할 문자
열인 “true”, “fasle”가 저장된
첨자를 선택
 함수 isalnum()의 반환 값이
0이면 “fasle”가 출력되고 반
환 값이 0이 아니면 “true”가
출력
25
문자열 함수
 문자열 관련 함수
 문자열 처리 라이브러리 함수는 헤더파일 string.h에 함수 원형이 정의
 문자열 처리 라이브러리 함수는 대부분 이름 str----()로 명명
 함수 strcmp()
 두 문자열을 비교하는 함수
 함수 strlen()
 문자열에서 처음의 NULL 문자를 제외한 문자열의 길이를 반환
 함수 strcpy()
 앞 문자열에 처음에 뒤 문자열을 복사하여 그 복사된 문자열을 반환
 함수 strcat()
 앞 문자열에 뒤 문자열을 연결(concatenate) 저장하여, 이 연결된 문자
열을 반환
 함수 strtok()
 앞 문자열에서 뒤 문자열에 포함되어 있는 구분자를 기준으로 토큰을
추출
26
함수 strcmp()
 함수원형
 두 문자열을 비교하는 함수
int
strcmp(const char *, const char *);
 비교방법
 전달인자인 두 문자열을 사전(lexicographically) 상의 순서로 비교
 앞과 뒤의 문자열을 사전 순서로 비교하여 앞 문자열이 먼저 나오면 음
수, 뒤 문자열이 먼저 나오면 양수, 같으면 0을 반환
printf(“%d”, strcmp(“a”, “ab”)); //음수 출력
printf(“%d”, strcmp(“ab”, “a”)); //양수 출력
printf(“%d”, strcmp(“ab”, “ab”)); //0 출력
 비교 기준은 아스키 코드 값이다.
 두 문자가 같다면 계속 다음 문자를 비교하여, 다른 문자에서 앞 문자
가 작으면 음수, 뒤 문자가 작으면 양수, 같으면 0을 반환
 대문자가 소문자보다 아스키 코드 값이 작으므로 strcmp(“java”, “javA”)
는 양수를 반환
27
예제 소스
 파일 strcomp.c
 문자열 비교 함수
strcmp()를 이용하
여 입력된 두 행의
문자열을 비교하는
프로그램
 두 문자열에서 함수
strcmp()를 적용한
비교 결과를 출력
 두 문자열을 구성하
는 각 문자의 아스키
코드 값을 출력
 각 문자 별로 크고
작음을 구분하여 각
각 ‘<’, ‘>’, ‘=’ 문자를
적절히 출력
28
함수 strcat()
 함수 원형
char * strcat(char *, const char *);
 앞 문자열의 마지막 NULL 문자에서부터 뒤 문자열의 NULL 문자까지 연결하
여, 앞의 문자열 주소를 반환
char stmt[25] = "Java is o-o ";
char lang[] = "language.";
printf("%s\n", strcat(stmt, lang));
29
함수 strcpy()
 함수원형
char * strcpy(char *, const char *);
char * strncpy(char *, const char *, size_t n);
 앞 문자열에 처음에 뒤 문자열을 복사하여 그 복사된 문자열을 반환
 앞 문자열에 처음에 뒤 문자열을 NULL 문자까지, 최대 n개를 복사하여 그 복
사된 문자열을 반환한다.
스
char stmt[30] = "Java is object oriented ";
printf("%s\n", strcpy(stmt, “C”));
30
예제 소스
 파일 stringfunc.c
 연결 함수 strcat(), strncat()과
복사 함수 strcpy(), strncpy()를
이용하여 함수의 기능을 살펴
보는 프로그램
31
함수 strtok()
 함수원형
char * strtok(char *, const char *);
 앞 문자열에서 뒤 문자열에 포함되어 있는 구분자를 기준으로 토큰을 추출
 사용방법
 다음 문자열에서 구분자를 공백 문자, 쉼표(,)로 토큰을 분리
 "C, C++ language are best!"
char *delimiter = " ,";
char str1[] = "C, C++ language are best!";
ptoken = strtok(str1, delimiter);
while ( ptoken != NULL ) {
printf("%s\n", ptoken);
ptoken = strtok(NULL, delimiter);
}
 분리되는 토큰 단어는 “C”, “C++”, “language”, “are”, “best!” 5개
32
예제 소스
 파일 strtok.c
 문자열 추출 함수
strtok()의 기능을 살
펴보는 프로그램
33
예제 소스
 파일 strtok.c
 문자열 추출 함수 strtok()의 기능
을 살펴보는 프로그램
34
명령어 줄
35
Command line argument
 명령어 줄 전달인자
 명령어 라인에서 입력하는 문자열을 프로그램으로 전달하는 방법이
명령어 줄 전달인자
 프로그램에서 명령어 줄 전달인자는 메인함수의 인자로 기술
 지금까지는 명령어 줄 전달인자를 이용하지 않았으므로 메인의 인자
를 void로 기술
 프로그램에서 명령어 줄 전달인자를 받으려면 다음과 같이 메인 함수
에서 두 개의 인자를 기술
int main(int argc, char *argv[])
{
…
}
 메인 함수의 전달 인자 argc는 명령어 줄에서 입력한 문자열의 수
 메인 함수의 전달 인자 argv[]는 명령어 줄에서 입력한 문자열을 전달
받는 문자 포인터 배열
 여기서 주의할 점은 실행 프로그램 이름도 하나의 명령어 줄 인자에 포
함된다는 사실
36
실행 파일 commandline
 실행 파일 이름이 commandline이고 옵션으로 red blue green으로, 프
로그램을 실행하고 있는 명령어 줄
 다음과 같은 구조로 문자열을 전달
37
예제 소스
 파일
commandline.c
 명령어 줄 전달
인자를 이용한
프로그램
38
Visual C++에서 명령어 인자
 명령어 인자를 설정
 메뉴 Project의 하부
메뉴 Settings…를 눌
러 다음 대화상자에
서 설정
 단축 키 Alt+F7을 이
용
 대화상자 Project
Settings에서 탭
Debug를 누르고 중
간의 Program
arguments:
 하단의 입력 상자
에 인자를 기술
 이 입력 상자에는
실행파일 이름 뒤
의 옵션만을 기술
39
프로그램 연습
 프로그램 목적
 10줄 이내에 걸쳐 문장을 입력 받아 행마다 입력된 문자열에서 모든
단어를 추출해 내는 프로그램
 이용함수
 줄을 입력 받기 위하여 함수 gets()를 이용하고,
 토큰을 나누기 위해서 함수 strtok()를 이용하며,
 각각의 토큰 길이를 알기 위하여 strlen()을 이용
 다음 조건을 만족
 10줄 이하의 여러 줄에 원하는 문장을 입력하고, 입력이 다 되었으면
새로운 줄 처음에 키 ctrl+Z, 그리고 Enter 키를 입력하면 결과가 출력
되도록 하자
 토큰은 빈칸, 쉼표(,), 마침표(.), 느낌표(!) 그리고 탭(\t)으로 구분되는
단어로 길이와 토큰 문자열을 출력한다.
40
41