Upload
tuan
View
360
Download
0
Embed Size (px)
DESCRIPTION
제 12 장 문자와 문자열. 쉽게 풀어쓴 C 언어 Express. C Express. 이번 장에서 학습할 내용. 인간은 문자를 사용하여 정보를 표현하므로 문자열은 프로그램에서 중요한 위치를 차지하고 있다 . 이번 장에서는 C 에서의 문자열 처리 방법에 대하여 자세히 살펴볼 것이다. 문자 표현 문자열 표현 문자열 입출력 문자 처리 함수 문자열 변환 함수. 문자 표현. 아스키코드 (ASCII code ) : 표준적인 8 비트 문자 코드 0 에서 127 까지의 숫자를 이용하여 문자 표현 - PowerPoint PPT Presentation
Citation preview
© 2012 생능출판사 All rights reserved
쉽게 풀어쓴 C 언어 Express쉽게 풀어쓴 C 언어 Express
C Express제 12 장 문자열
© 2012 생능출판사 All rights reserved
이번 장에서 학습할 내용
• 문자 표현• 문자열 표현• 문자열 입출력• 문자 처리 함수• 문자열 변환 함수
인간은 문자를 사용하여 정보를
표현하므로 문자열은 프로그램에서 중요한 위치를 차지하고 있
다 . 이번 장에서는 C에서의 문자열 처리
방법에 대하여 자세히 살펴볼 것이다 .
© 2012 생능출판사 All rights reserved
문자 표현· 아스키코드 (ASCII code): 표준적인 8 비트 문자 코드
· 0 에서 127 까지의 숫자를 이용하여 문자 표현· 유니코드 (unicode): 표준적인 8/16/32 비트 문자 코드
· 전세계의 모든 문자를 일관되게 표현하고 다룰 수 있도록 설계
C 에서 문자는
숫자로 표현 됩니다 .6
5
69
71
74 7
8
© 2012 생능출판사 All rights reserved
문자열 표현· 문자열 (string): 문자들이 여러 개 모인 것
· "Hello" // length = 5· " 변수 score 의 값은 %d 입니다 "
· 문자열의 저장 : 문자 배열 사용· NULL 문자 ('\0'): 문자열의 끝을 나타냄· NULL 문자열 (""): length = 0
"Hello"
H e l l o \0
'A'
A
"A"
A \0
""
\0
© 2012 생능출판사 All rights reserved
문자 변수와 문자 상수#include <stdio.h>int main(void){
char code1 = 'A';char code2 = 65;
printf("code1=%c, code1=%d\n", code1, code1);printf("code2=%c, code2=%d\n", code2, code2);
return 0;}
code1=A, code1=65code2=A, code2=65
65
© 2012 생능출판사 All rights reserved
#include <stdio.h>int main(void){
unsigned char code;
for (code = 33; code < 127; code++)printf(" 아스키 코드 %d 은 %c 입니다 .\n", code, code);
return 0;}
아스키 코드 출력
아스키 코드 33 은 ! 입니다 ....아스키 코드 65 은 A 입니다 ....아스키 코드 97 은 a 입니다 ....아스키 코드 126 은 ~ 입니다 .
© 2012 생능출판사 All rights reserved
문자열 예제#include <stdio.h>int main(void){
int i;char str[4];str[0] = 'a';str[1] = 'b';str[2] = 'c';str[3] = '\0';
i = 0;while (str[i] != '\0') {
printf("%c", str[i]);i++;
}
return 0;}
abc
© 2012 생능출판사 All rights reserved
문자 배열의 초기화· char str[4] = { 'a', 'b', 'c', '\0' };
· char str[4] = "abc";
· char str[4] = "abcdef"; // X
· char str[6] = "abc";
· char str[4] = "";
· char str[ ] = "abc";
© 2012 생능출판사 All rights reserved
문자열 예제#include <stdio.h>int main(void){
char str1[6] = "Seoul";char str2[3] = { 'i', 's' };char str3[ ] = "the capital of Korea.";
printf("%s %s %s\n", str1, str2, str3);
return 0;}
Seoul is the capital of Ko-rea.
© 2012 생능출판사 All rights reserved
문자열 예제#include <stdio.h>int main(void) {
char src[] = "The worst things to eat before you sleep";char dst[100];int i;printf(" 원본 문자열 = %s\n", src);for (i = 0; src[i]; i++) // src[i] != '\0'
dst[i] = src[i];dst[i] = '\0';printf(" 복사된 문자열 = %s\n", dst);return 0;
}
원본 문자열 = The worst things to eat before you sleep복사된 문자열 = The worst things to eat before you sleep
© 2012 생능출판사 All rights reserved
문자열 길이#include <stdio.h>int main(void){
char str[30] = "Hello";int i = 0;while (str[i]) i++;printf(" 문자열 \"%s\" 의 길이는 %d 입니다 .\n", str, i);return 0;
}문자열 "Hello" 의 길이는 5 입니다 .
0 1 2 3 4 5
H e l l o \0
© 2012 생능출판사 All rights reserved
문자열 저장
1. 각 문자 배열 원소에 일일이 대입· str[0] = 'W';· str[1] = 'o';· str[2] = 'r';· str[3] = 'l';· str[4] = 'd';· str[5] = '\0';
2. strcpy 함수를 사용하여 문자 배열에 복사· strcpy(str, "World"); // 추후 학습
© 2012 생능출판사 All rights reserved
문자열 상수· 문자열 상수 ("…"): read-only 메모리 영역에 저장
· 수정 불가· char *p = "Hello";
· p[0] = 'h'; (X)· p = "World"; (O)· sizeof p : 4(8)· length : 5
· char a[ ] = "Hello";· a[0] = 'h'; (O)· a = "World"; (X)· sizeof a : 6· length : 5
0 1 2 3 4 5
H e l l o \0100p100
0 1 2 3 4 5
H e l l o \0a
© 2012 생능출판사 All rights reserved
문자 입출력 함수함수 기능
int getchar(void) 하나의 문자를 읽어서 반환 , 입력 실패의 경우 EOF 반환
putchar(int c) 변수 c 에 저장된 문자 출력
scanf("%c", &c) 하나의 문자를 읽어서 변수 c 에 저장
printf("%c", c); 변수 c 에 저장된 문자 출력
· #define EOF (-1) // <stdio.h>· End Of File
© 2012 생능출판사 All rights reserved
getchar(), putchar()#include <stdio.h>int main(void){
int ch; // 정수형에 주의
while((ch = getchar()) != EOF)putchar(ch);
return 0;}
ABABCC^Z
입력
출력
© 2012 생능출판사 All rights reserved
버퍼링 (buffering)
· 엔터키 ('\n') 를 쳐야만 입력을 받는 이유
라인 단위로 버퍼에 저장 엔터키가 입력되면 프로그램으로 전달
키보드 버퍼 (buffer)
#include <stdio.h>
int main(void){ int ch;
ch = getchar(); ... ...}
프로그램
© 2012 생능출판사 All rights reserved
문자열 입출력 함수함수 기능
scanf("%s", s) 문자열을 읽어서 s 에 저장 ( 띄어쓰기 단위로 입력 )
printf("%s", s) 문자열 s 출력
char *gets(char *s) 한 줄을 읽어서 s 에 저장 , s 를 반환
puts(const char *s) 문자열 s 출력
© 2012 생능출판사 All rights reserved
gets(), puts()
· gets(): '\n' 을 만날 때까지 한 줄을 입력하여 str 에 저장· '\n' 은 읽어들이지만 저장하지는 않음· 입력이 성공하면 str 반환· 입력이 실패하거나 파일 끝을 만나면 NULL 포인터 반환
· puts(): str 과 '\n' 을 출력· puts(s) printf("%s\n", s)
· char s[100];gets(s); // 입력 : ab cd\n s: ab cd\0puts(s); // s: ab cd\0 출력 : ab cd\n
· char s[100];while (gets(s)) // gets(s) != NULL puts(s);
char *gets(char *str);puts(const char *str);
© 2012 생능출판사 All rights reserved
문자열 입출력#include <stdio.h>int main(void) {
char name[100], address[100];
printf(" 이름을 입력하시오 : "); gets(name);printf(“ 주소를 입력하시오 : "); gets(address);puts(name); puts(address);
return 0;}
이름을 입력하시오 : 홍길동주소를 입력하시오 : 서울시 종로구 100번지홍길동서울시 종로구 100 번지
© 2012 생능출판사 All rights reserved
문자 처리 함수· #include <ctype.h>
함수 기능 (int 형으로 참 / 거짓 반환 )
isalpha(c) c 가 영문자인가 ? (a~z, A~Z)
isupper(c) c 가 대문자인가 ? (A~Z)
islower(c) c 가 소문자인가 ? (a~z)
isdigit(c) c 가 숫자인가 ? (0~9)
isalnum(c) c 가 영문자나 숫자인가 ? (a~z, A~Z, 0~9)
isxdigit(c) c 가 16 진수 숫자인가 ? (0~9, A~F, a~f)
isspace(c) c 가 공백 문자인가 ? (' ', \n, \r, \t, \v, \f)
ispunct(c) c 가 구두점 문자인가 ?
isprint(c) c 가 출력 가능 문자인가 ?
isgraph(c) c 가 그래프 문자인가 ?
iscntrl(c) c 가 제어 문자인가 ?
· ASCII 문자 분류 control: 0~31,
127(DEL) printing: 32~126
blank: ' '(32) punctuation: !, ", … alphanumeric
alphabet(letter) - uppercase: A~Z - lowercase: a~z number(digit): 0~9
graph: printing – ' '(32)
punctuation: graph – alphanu-meric
whitespace: ' ', \n, \r, \t, \v, \f
함수 기능 (int 형으로 문자 반환 )
toupper(c)c 의 대문자 반환 (c 가 소문자가 아니면 c 반환 )
tolower(c)c 의 소문자 반환 (c 가 대문자가 아니면 c 반환 )
© 2012 생능출판사 All rights reserved
대문자 변환#include <stdio.h>#include <ctype.h>
int main(void){
int c;
while ((c = getchar()) != EOF)putchar(toupper(c));
return 0;}
abc123ABC123^Z
© 2012 생능출판사 All rights reserved
문자 검사#include <stdio.h>#include <ctype.h> int main(void){
int c = 'A';
printf("isdigit(%c) = %d\n", c, isdigit(c));printf("isalpha(%c) = %d\n", c, isalpha(c));printf("islower(%c) = %d\n", c, islower(c));printf("ispunct(%c) = %d\n", c, ispunct(c));printf("isxdigit(%c) = %d\n", c, isxdigit(c));printf("isprint(%c) = %d\n", c, isprint(c));
return 0;}
isdigit(A) = 0isalpha(A) = 1islower(A) = 0ispunct(A) = 0isxdigit(A) = 128isprint(A) = 1
if (isupper(c)) …
© 2012 생능출판사 All rights reserved
문자열 처리 함수
함수 기능
size_t strlen(cs) cs 의 길이 반환
char *strcpy(s, ct) ct 를 s 에 복사 , s 반환
char *strncpy(s, ct, n)
ct 를 s 에 복사 , 최대 n 문자만 복사 , s 반환
char *strcat(s, ct) ct 를 s 에 끝에 접속 , s 반환
char *strncat(s, ct, n)
ct 를 s 에 끝에 접속 , 최대 n 문자만 접속 , s 반환
int strcmp(cs, ct) cs 와 ct 의 비교 결과 반환
int strncmp(cs, ct, n)
cs 와 ct 의 비교 결과 반환 , 최대 n 문자만 비교
char *strchr(cs, c) cs 에서 c 가 처음 나타난 위치 반환 , 없으면 NULL 반환
char *strrchr(cs, c)cs 에서 c 가 마지막으로 나타난 위치 반환 , 없으면 NULL
반환
char *strstr(cs, ct) cs 에서 ct 가 처음 나타난 위치 반환 , 없으면 NULL 반환
· #include <string.h>
(s: char *; cs, ct: const char*; c: int(char), n: int)
© 2012 생능출판사 All rights reserved
· strlen("Hello") : 5
· char s[100];strcpy(s, "Hello"); // s : "Hello"puts(strcpy(s, "Hello")); // Hello
· char s[100] = "Hello";strcat(s, " World"); // s : "Hello World"puts(strcat(s, " World")); // Hello World
strlen(), strcpy(), strcat()size_t strlen(const char *s) { const char *p = s; while (*p) p++; return (size_t)(p - s);}
char *strcpy(char *s, const char *t) { char *p = s; while ((*p++ = *t++)) ; return s;}
char *strcat(char *s, const char *t) { char *p = s; while (*p) p++; while ((*p++ = *t++)) ; return s;}
© 2012 생능출판사 All rights reserved
문자열 처리#include <stdio.h>#include <string.h>int main(void){
char string[100];strcpy(string, "Hello world from "); strcat(string, "strcpy "); strcat(string, "and "); strcat(string, "strcat!"); printf("string = %s\n", string);return 0;
}string = Hello world from strcpy and strcat!
© 2012 생능출판사 All rights reserved
문자열 비교 : strcmp()int strcmp(const char *s1, const char *s2);
반환 값 관계
- s1 < s2
0 s1 = s2
+ s1 > s2
s2
s1
s t r c p \0
s t r c m \0p
y
= = = = > m 이 p 보다 아스키 코드값이 작으므로 음수 반환
· 숫자 < 대문자 < 소문자 < 한글
· if (strcmp(s1, s2)) // s1 ≠ s2 ? if (strcmp(s1, s2) != 0)
· if (!strcmp(s1, s2)) // s1 = s2 ? if (strcmp(s1, s2) == 0)
© 2012 생능출판사 All rights reserved
문자열 비교#include <stdio.h>#include <string.h>int main( void ) {
char s1[80], s2[80];int result;
printf(" 첫번째 단어를 입력하시오 : "); scanf("%s", s1);printf(" 두번째 단어를 입력하시오 : "); scanf("%s", s2);result = strcmp(s1, s2);if (result < 0)
printf("%s 가 %s 보다 앞에 있습니다 .\n", s1, s2);else if (result > 0)
printf("%s 가 %s 보다 뒤에 있습니다 .\n", s1, s2);else
printf("%s 와 %s 가 같습니다 .\n", s1, s2);
return 0;}
첫번째 단어를 입력하시오 : Hello두번째 단어를 입력하시오 : WorldHello 가 World 보 다 앞 에 있습니다 .
© 2012 생능출판사 All rights reserved
문자 검색#include <stdio.h>#include <string.h>int main(void) {
char s[ ] = "language"; char c = 'g';char *p;int loc;
p = strchr(s, c);loc = (int)(p - s);if (p)
printf( " 첫번째 %c 가 %d 에서 발견되었음 \n", c, loc);else
printf( "%c 가 발견되지 않았음 \n", c);
return 0;}
첫번째 g 가 3 에서 발견되었음
© 2012 생능출판사 All rights reserved
문자열 검색#include <stdio.h>#include <string.h>int main(void) {
char s[ ] = "A joy that's shared is a joy made double";char sub[ ] = "joy";char *p;int loc;
p = strstr(s, sub);loc = (int)(p - s);if (p)
printf( " 첫번째 %s 가 %d 에서 발견되었음 \n", sub, loc);else
printf( "%s 가 발견되지 않았음 \n", sub);
return 0;}
첫번째 joy 가 2 에서 발견되었음
© 2012 생능출판사 All rights reserved
문자열 처리 ( 보충 )#include <stdio.h>#include <string.h>void main() { char s[100], *p;
puts(strcpy(s, "ab#")); // ab# puts(strncpy(s, "ABC", 2)); // AB# puts(strncpy(s, "12", 3)); // 12 strcpy(s, "AB"), puts(strcat(s, "123")); // AB123 strcpy(s, "AB"), puts(strncat(s, "123", 2)); // AB12
printf("%d\n", strcmp(" 가 ", "a")); // + printf("%d\n", strcmp("a", "A")); // + printf("%d\n", strcmp("A", "0")); // + printf("%d\n", strcmp("ab", "ab")); // 0 printf("%d\n", strcmp("ab", "abc")); // - if (!strncmp("abc", "abC", 2)) printf("equal\n"); // equal
if ((p = strchr("abab", 'b'))) puts(p); // bab if ((p = strrchr("abab", 'a'))) puts(p); // ab if ((p = strstr("AABC", "AB"))) puts(p); // ABC}
© 2012 생능출판사 All rights reserved
토큰 분리 : strtok()
t1 = strtok(s, " \t"); // 첫 번째 토큰t2 = strtok(NULL, " \t"); // 두 번째 토큰t3 = strtok(NULL, " \t"); // 세 번째 토큰t4 = strtok(NULL, " \t"); // 네 번째 토큰
char *strtok(char *s, const char *delimiters);
· delimiters 에 속한 분리자로 구분되는 s 의 토큰 반환· 토큰이 없으면 NULL 포인터 반환· 계속 분리하는 경우 , s 에 NULL 포인터 사용
· 분리자가 공백 문자나 탭 문자인 경우
© 2012 생능출판사 All rights reserved
토큰 분리#include <stdio.h>#include <string.h>int main(void) {
char s[] = "Man is immortal, because he has a soul";char *seps = " ,\t\n";char *token;
token = strtok(s, seps); while (token) {
printf(" 토큰 : %s\n", token);token = strtok(NULL, seps);
}
return 0;}
토큰 : Man토큰 : is토큰 : immortal토큰 : because토큰 : he토큰 : has토큰 : a토큰 : soul
© 2012 생능출판사 All rights reserved
문자열 ↔ 수치 변환· 문자열과 수치
· #include <stdio.h>
src[0] src[1] src[2] src[3] src[4]
3 6 . 5 \0 36.5
v
함수 기능
sscanf(s, …) scanf 와 유사 ; 단 , 문자열 s 에서 입력 ( 문자열 수치 )
sprintf(s, …) printf 와 유사 ; 단 , 문자열 s 에 출력 ( 수치 문자열 )
© 2012 생능출판사 All rights reserved
문자열 ↔ 수치 변환#include <stdio.h>int main( void ){
char s1[ ] = "100 200 300";char s2[30];int value;
sscanf(s1, "%d", &value);printf("%d\n", value);sprintf(s2, "%d", value);printf("%s\n", s2);
return 0;}
100100
© 2012 생능출판사 All rights reserved
문자열 ↔ 수치 변환#include <stdio.h>
void process(const char *filename) {printf("%s\n", filename);// do something
}
int main(void) {char filename[100];int i;for (i = 0; i < 6; i++)
sprintf(filename, "image%d.jpg", i);process(filename);
}return 0;
}
image0.jpgimage1.jpgimage2.jpgimage3.jpgimage4.jpgimage5.jpg
© 2012 생능출판사 All rights reserved
문자열 수치 변환 함수· #include <stdlib.h>
함수 기능
int atoi(const char *str); str 을 int 형으로 변환
long atol(const char *str); str 을 long 형으로 변환
double atof(const char *str); str 을 double 형으로 변환
· sscanf 보다 빠름
© 2012 생능출판사 All rights reserved
문자열 수치 변환 #include <stdio.h>#include <stdlib.h>
int main(void){
char s1[ ] = "100", s2[ ] = "12.93";int i; double d, result;
i = atoi(s1);d = atof(s2);result = i + d;printf(" 연산 결과는 %g 입니다 .\n", result);
return 0;}
연산 결과는 112.93 입니다 .
© 2012 생능출판사 All rights reserved
문자열 배열
char menu[3][6] = {"quit","open","close"
};
· 2 차원 문자 배열
q u i t \0
\0
o p e n \0
\0
c l o s e \0
char *menu[3] = {"quit","open","close"
};
· 문자 포인터 배열
q u i t \0
c l o s e \0
o p e n \0
menu
// 메뉴 출력for (i = 0; i < 3; i++)
printf("%d: %s\n", i, menu[i]);
menu
© 2012 생능출판사 All rights reserved
문자열 배열#include <stdio.h>int main(void) {
int i;char fruits[3][20];
for (i = 0; i < 3; i++) {printf(" 과일 이름을 입력하시오 : ");scanf("%s", fruits[i]);
}for (i = 0; i < 3; i++)
printf("%d 번째 과일 : %s\n", i, fruits[i]);
return 0;}
과일 이름을 입력하시오 : 사과과일 이름을 입력하시오 : 배과일 이름을 입력하시오 : 포도0 번째 과일 : 사과1 번째 과일 : 배2 번째 과일 : 포도
© 2012 생능출판사 All rights reserved
영한 사전#include <stdio.h>#include <string.h>#define ENTRIES 5int main(void) {
int i;char dic[ENTRIES][2][30] = {
{ "book", " 책 " },{ "boy", " 소년 " },{ "computer", " 컴퓨터 " },{ "language", " 언어 " },{ "rain", " 비 " }
};char word[30];
printf(" 단어를 입력하시오 : "); scanf("%s", word);for (i = 0; i < ENTRIES; i++)
if (!strcmp(dic[i][0], word)) {printf("%s: %s\n", word, dic[i][1]);return 0;
}printf(" 사전에서 발견되지 않았습니다 .\n");return 1;
}
단어를 입력하시오 : bookbook: 책