4장 문자열과 입출력 포맷 이경호 2018-09-17
목차 문자열을 만들고 저장하는 방법 기호 상수를 만드는 방법 printf() 함수 : strlen() scanf() Q&A 2018-09-17
함수 strlen() 문자열의 크기를 문자 수로 알아냄. sizeof 와는 다름 Ex) #include <stdio.h> #include <string.h> // strlen()을 사용하기 위해 int main() { int size, letters; char name[40]; // name은 영문자로 39개를 넣을 수 있는 배열로 마지막은 널문자가 들어감. // 40바이트임. printf("이름이 뭐예요?\n"); scanf("%s", name); // name은 주소임. size = sizeof name; // 문자열의 크기를 알아냄. letters = strlen(name); // 문자열의 길이를 알아냄. printf("그리고 이름이 %d글자니까,\n", letters); printf("저장하려면 %d바이트가 필요합니다.\n", size); return 0; } 2018-09-17
함수 strlen() sizeof는 name[40]자체의 크기를 알아냄. 실행화면 sizeof는 name[40]자체의 크기를 알아냄. strlen()는 널문자 전까지 읽기 때문에 문자의 수를 나타냄. 2018-09-17
문자열을 만들고 저장하는 방법 문자열이란? 문자열(Character string)은 하나 또는 여러 개의 문자들이 연속되어 있는 것 ex) "CHONNAM UNIVERSITY" -> 여기서 큰 따옴표는 문자열의 일부가 아닌, 컴파일러에게 하나의 문자열을 감싸고 있다고 알리는 것 2018-09-17
문자열을 만들고 저장하는 방법 C는 char형 배열에 문자열을 저장함. 문자열에 있는 문자들은 연속적인 메모리 셀들에, 셀당 한 문자씩 저장됨. 예를 들어 name[40]에 abcd를 입력하면 [a|b|c|d| | | | |… | |\0] ┗ 40개 ┛ 배열이란? 간단하게 말하면 연속되어 있는 여러개의 메모리 셀. 정확하게 말하면 동일한 데이터형을 가진 여러 데이터 원소들이 메모리에 순서대로 나열되어 있는 연속물. 위 예제의 name[40]은 40개의 메모리 셀(또는 원소)를 가진 배열임. 2018-09-17
문자열을 만들고 저장하는 방법 -> 여기서 \0은 널문자로 \0 값은 정수값으로는 0 임. 그리고, 정수 0값을 아스키코드값은 실제상에는 아무것도 보이지 않은 널값임. 또한 \0값까지 문자를 읽음. ( 널 문자를 직접 넣을 필요는 없음. 컴파일러나 scanf()가 입력을 읽을 때 알아서 넣어줌. ) ex) #include <stdio.h> void main() { printf("여기를 \0 보세요"); } 실행화면 2018-09-17
기호 상수를 만드는 방법 기호 상수의 이점 기호 상수를 사용할 경우 프로그램의 여러 곳에서 사용했을 경우, 바꿀 때 기호 상수의 정의만 간단하게 바꾸면 편리함. 기호 상수의 사용법 : - 변수설정 int pie = 3.14159 ; -> 프로그램에서 우연히 값을 변경시킬수 있음. 비추 2018-09-17
기호 상수를 만드는 방법 - 전처리기 #define PIE 3.14159 -> 프로그램이 컴파일될 때, PIE가 사용된 모든 곳이 값 3.14159로 대체됨.프로그램을 실행할 시점에서 모든 대체가 이미 끝난 상태임. (PIE의 이유: 상수이름을 대문자로 표기하는것이 C의 전통. 변수가 아니라 상수라는걸 즉시 알 수 있음.) 2018-09-17
기호 상수를 만드는 방법 Ex) 타이핑한 내용 #define taxrate 0.015 Int main(void) { ……… bill = taxrate * sum; ………} 전처리후 { ……… bill = 0.015 * sum; ………} 2018-09-17
기호 상수를 만드는 방법 - const 변경자 const int MONTHS = 12; // MONTHS는 12를 나타내는 기호 상수 -> MONTHS를 읽기 전용 값으로 만듬. 즉, MONTHS를 표시할 수 있고, 계산에도 사용할 수 있지만 MONTHS의 값은 변경 불가. 2018-09-17
printf(), scanf() printf(), scanf() -> 가장 다용도로 사용되는 입출력 함수. 즉, 둘 다 하나의 포맷 문자열과 전달인자 리스트를 사용함. 2018-09-17
printf() 변수의 데이터형에 따라 printf()에 내리는 지시는 다름. 예) 정수를 출력할 때에는 %d를 사용, 문자열을 사용할 때에는 %s를 사용. 이들을, 출력할 데이터를 어떤 포맷으로 변환해야 하는지 지정하기 때문에 포맷 지정자라고 부름. 2018-09-17
printf() 포맷지정자 상응하는 출력 데이터형 %a 부동소수점수, 16진수, p-표기 포맷지정자 상응하는 출력 데이터형 %a 부동소수점수, 16진수, p-표기 %A 부동소수점수, 16진수, P-표기 %c 하나의 문자 %d 부호 있는 10진 정수 %e 부동소수점수 e-표기 %E 부동소수점수 E-표기 %f 부동소수점수, 10진수 표기 %g 값에 따라 %f, %e 사용, 지수부가 -4보다 작거나, 정밀도보다 크거나 같으면 %e 사용 %G 값에 따라 %f, %E 사용, 지수부가 -4보다 작거나, 정밀도보다 크거나 같으면 %E 사용 %i 부호있는 10진정수 (%d와 같다) %o 8진정수 %p 포인터 %s 문자열 %u 부호없는 10진 정수 %x 부호없는 16진 정수 10진 숫자 0f 사용 %X 부호없는 16진 정수 10진 숫자 0F 사용 %% 퍼센트 기호 출력 2018-09-17
printf() printf()를 사용하는 형식 printf(Control-string, item1, item2, ...); ex) printf("%d명이 %f잔의 커피를 마셨다.\n", number, coffee); 여기서 Control-string은 " " 안에 있는 문구임. number와 espresso에 대응하는 2개의 포맷 지정자를 가지고 있음. 2018-09-17
printf() 포맷 문자열은 두 가지 정보를 지님. - 실제로 출력될 문자들 명이 잔의 커피를 마셨다. - 포맷 지정자 명이 잔의 커피를 마셨다. - 포맷 지정자 %d %f 2018-09-17
printf() printf()의 포맷 변경자 %와 포맷 문자 사이에 포맷 변경자를 삽입하면, 기본적인 포맷 지정을 변경할 수 있음. 플래그 : 다음표. h : 정수형 포맷 지정자와 함께 사용됨. short int 형 또는 unsigned int 형 값을 나타냄. hh : 정수형 포맷 지정자와 함께 사용됨. signed char형 또는 unsigned char형 값을 나타냄. l : 정수형 포맷 지정자와 함께 사용됨. long int 형 unsigned long int 형 값을 나타냄. ll : 정수형 포맷 지정자와 함께 사용됨. long long int 형 unsigned long long int 형 값을 나타냄. L : 부동소수점형 포맷 지정자와 함께 사용됨. Long double형 값을 나타냄. 2018-09-17
printf() 플래그 : - : 항목이 왼쪽 정렬로 출력. + : 부호 있는 수를 출력할 때, 양수이면 +, 음수이면 - 부호를 붙임. 스페이스 : 부호 있는 수를 출력할 때, 양수이면 부호 없이 스페이스를 하나 붙이고, 음수이면 -를 붙인다. ( + 플래그는 스페이스를 무시한다. ) # : %o의 경우에 하나의 0을 앞에 붙인다. %x와 %X인 경우에 0x와 0X를 각각 붙인다. 모든 부동소수점형에 대해, #은 소수점 아래에 아무 것도 없더라도 소수점을 출력하도록 한다. %g와 %G의 경우에는 뒤에 붙는 0이 제거되지 않도록 한다. 0 : 필드 너비에서 남은 공간을 스페이스 대신 0으로 채운다. (플래그가 있거나, 정수형에 정밀도가 지정되어 있으면 이 플래그는 무시된다.) 2018-09-17
printf() ex)부동소수점형 포맷 지정자 사용 #include <stdio.h> int main(void) { const double RENT = 3852.99; // const로 지정한 상수 printf("*%f*\n", RENT); printf("*%e*\n", RENT); printf("*%4.2f*\n", RENT); printf("*%3.1f*\n", RENT); printf("*%10.3f*\n", RENT); printf("*%10.3e*\n", RENT); printf("*%+4.2f*\n", RENT); printf("*%010.2f*\n", RENT); return 0; } 2018-09-17
printf() #include <stdio.h> int main(void) { printf("%x %X %#x\n", 31, 31, 31); printf("**%d**% d**% d**\n", 42, 42, -42); printf("**%5d**%5.3d**%05d**%05.3d**\n", 6, 6, 6, 6); return 0; } 2018-09-17
printf() ex) #include <stdio.h> #define BLURB "Authentic imitation!" int main(void) { printf("/%2s/\n", BLURB); printf("/%24s/\n", BLURB); printf("/%24.5s/\n", BLURB); printf("/%-24.5s/\n", BLURB); return 0; } 2018-09-17
printf() 잘못 짝지어진 포맷 지정자 #include <stdio.h> #define PAGES 336 #define WORDS 65618 int main(void) { short num = PAGES; short mnum = -PAGES; printf("short형, unsigned short형 num: %hd %hu\n", num, num); printf("short형, unsigned short형 -num: %hd %hu\n", mnum, mnum); printf("int형, char형 num: %d %c\n", num, num); printf("int형, short형, char형 WORDS: %d %hd %c\n", WORDS, WORDS, WORDS); return 0; } 2018-09-17
scanf() scanf()는 문자열 입력을 다양한 포맷으로 변환한다. printf()와 마찬가지로, 포맷 문자열과, 전달인자 리스트를 사용. 차이점 -> 전달인자 리스트 printf() 함수는 변수 이름, 상수, 수식을 사용. scanf() 함수는 변수를 가리키는 포인터를 사용. -> scanf()를 사용하여 문자열을 읽어 문자 배열 안에 넣는다면, & 기호를 사용하지 않는다. 2018-09-17
scanf() Scanf()함수는 printf() 함수와 거의 동일한 포맷 지정자들을 사용. 차이점 -> printf()함수는 float형, double형에 %f,%e,%E,%g,%G를 사용하지만 scanf()함수는 float형에 대해서만 이들을 사용, double형에 대해서는 l 변경자를 요구. scanf()는 화이트스페이스(스페이스, 탭, 개행)을 만나면, 화이트스페이스가 아닌 문자가 나타날 때까지 건너뜀. 2018-09-17
scanf() %c를 제외한 포맷 지정자들은, 입력 값 앞에 오는 화이트스페이스를 자동으로 무시함. 즉, scanf("%d%d",&n,&m)와 scanf("%d %d",&n,&m)는 동일하게 작동. %c의 경우에, 포맷문자열에 스페이스 문자를 추가하면 다르게 동작. 예) scanf(“%c”, &ch) 명령은 입력에서 만나는 첫 문자를 무조건 읽음. -> 스페이스를 누를경우 스페이스를 읽음. scanf(“ %c”, &ch) 는 화이트스페이스는 건너뛰고, 화이트스페이스가 아닌 첫 문자를 읽음. -> 스페이스만 누를경우 읽지않음. 2018-09-17
Q&A 감사합니다. 2018-09-17