C언어 보충2 - 11, 12장

2017. 12. 6. 01:42

11장. 문자

 

1. 아스키코드(=128개의 문자, 크기는 4바이트이다 ex: sizeof('a')->4바이트)

종류: 숫자, 대문자, 소문자, 특수, 제어

'A'=65='\101'='\x41'

int 변수에 문자(아스키코드) 저장시

00000000 00000000 00000000 아스키

상위                                                하위

->아스키코드가 4바이트이니 정상저장

->char변수에 저장시 0은 다 짤리고 끝의 1바이트만 저장된다.

 

2. scanf함수에 문자입력하기

scanf("%ㅁ%ㅁ",&a);에서 %d와 %c의 차이

%d%d ->123 12 -> 스페이스나 개행은 숫자x라서 무시

%c%c -> a b -> a와 스페이스를 문자로인식

=>%c에서 스페이스를 무시하고 입력 받으려면 "_%c_%c" (_는 스페이스를 의미한다. 스페이스 대신 \t, \n가능)

 

※ 화이트 스페이스

화이트스페이스(Whitespace)는 에드윈 브래디(Edwin Brady)와 크리스 모리스(Chris Morris, cim)가 2003년 4월 1일(만우절)에 발표한 난해한 프로그래밍 언어이다. 문법에는 오로지 공백과 탭, 그리고 개행 문자만이 의미가 있으며, 인터프리터는 이 3종류의 공백 문자를 뺀 모든 문자를 무시한다.

 

참조: https://ko.wikipedia.org/wiki/%ED%99%94%EC%9D%B4%ED%8A%B8%EC%8A%A4%ED%8E%98%EC%9D%B4%EC%8A%A4_(%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D_%EC%96%B8%EC%96%B4)

 

int ch

scanf("%c",&ch);일시 오류(ch의 1바이트만 값이 입력되고 나머지 3바이트는 쓰레기값이 들어있다)

->단, ch를 int ch=0;으로 초기화했으면 문제가 되지않는다.

 

3. int getchar(void)

입력받은 데이터를 아스키코드(4바이트)로 변경해 반환

장점: scanf에 비해 가볍다

단점: scanf와는 달리 문자(1바이트)만 입력받는다.

특징: int형으로 반환한다

-> 이유: 문자입력종료인 ctrl+z를 입력하면 -1을 반환한다.(scanf와 getchar 둘다) 만일 파일을 입력받게 되면

255와 구분이 되지않는다. 따라서 int형으로 반환하여 -1과 255를 구분.

 

4. scanf와 버퍼

scanf는 1바이트씩 입력받아 버퍼에 저장하고 저장하는 변환문자형식(%d, %c등)에 맞추어 데이터를 변환시켜 변수에 저장한다.

 

5. getchar와 버퍼

getchar는 변수로 배열을 사용한다. 개행문자 \n를 끝으로 인식하고, 변수(=배열)에 개행문자 대신 널문자 \0를 넣는다.

∴ 유효문자로 만들어진 배열의 크기=입력문자열의 크기+1

-> 틀린개념이라 삭제, getchar은 한글자씩 입력받는다(335.p 예제를 착각)

 

->scanf의 경우

1. %d: \n를 끝으로 보되, 변수에 저장 x(숫자가 아니니까)

2. %c: \n를 끝으로 보되, 변수에 \n을 그대로 저장

 

6. 버퍼비우기

int fflush(FILE * stream)

fflush(stdin); -> 키보드 버퍼에 남은 데이터 제거

 

ex) 315\n25 연속입력시

getchar은 \n도 받아들임(문자니까)  -->이경우 fflush필요

scanf는 ㅡ%c의 경우 받아들임 -->이경우 fflush필요

      ㄴ%d의 경우 무시 

 

※stream의 의미 : http://newmkka.tistory.com/78 참조

 

 

 

12장. 문자열

1. 문자열과 포인터

문자열이름=이름, 시작주소

 -> 메모리에서 보면 배열에 저장하는것과 같다

문자열 수정시 포인터사용

 

*동일한 문자열을 여러군데에서 사용할 경우 같은 주소값을 공유한다.(즉 효율화를 위해 한곳에 문자열을 저장하고 이를 참조한다.)

 

 

- char *a="apple"

  printf("%s",a); -> apple('%s, 배열명'처럼)

- printf("%p","apple"); -> "apple"가 저장된 주소값 출력

- printf("%c",*"apple"); -> "apple"은 주소, 즉 *주소 -> a

- printf("%c",*("apple"+1)); -> 주소+정수==주소+(정수*자료형) ->p

- printf("%c","mango"[2]); -> 배열명[2]==시작주소[2]=="mango"[2]

 

2. 문자열 입력받기

scanf

- %c: 1글자만 입력받음

- %s: 문자열을 입력받는다. 입력시 개행문자를 입력하면 입력을 끝낼수 있고, 버퍼에는 중간에 들어간 공백, 탭문자와 끝문자로 저장된 개행문자까지 들어있다. 단, scanf를 이용해 입력받은 데이터가 저장되는 변수(배열)에는 버퍼에 존재하는 화이트스페이스(공백, 탭, 개행)이전까지의 문자들만 저장된다.

다시한번 입력받을시에는 첫번째 유효한 문자가 나올때까지 버퍼에 남아있는 화이트 스페이스를 무시한다

 

   ex) apple jam\n 

    - ① 변수에는 "apple"가 저장되고 뒤에 '\0'가 붙는다, 버퍼는 " jam\n"가 남아있음

    - ② 다시 scanf입력시, ' '는 무시하고 첫번째 유효숫자인 'j'부터 'm'까지 저장되고 끝에 '\0'붙음. 버퍼에는 '\n'가 남아있다

 

gets

char *gets(char *str) ->str: 입력받은 문자열을 저장할 배열

개행문자를 입력하면 입력을 끝낸다

입력받은 버퍼에서 공백, 탭문자, 개행를 포함해 한번에 전부 변수에 저장되고, \n을 \0으로 치환하여 배열에 저장한다.

 

fgets

형태: char *fgets(char *str, int n, FILE *stream) ->fgets(배열명, 배열크기, 입력장치)

장점: 입력받은 문자열에서 입력받을때 배열의 최대크기까지만 문자열을 입력받는다.

특징: 파일을 입력받는다(stdin을 사용하면 키보드입력)

개행 \n을 변환없이 그대로 입력받고 끝에 널문자 \0를 붙이고(즉 배열 끝에는 '\n', '\0'가 들어있다), 출력시 개행이 이루어지게 된다.

 

* scanf는 개행, 공백, 탭문자 '이전'까지만 저장한다

   scanf는 처음 입력받는 문자가 개행, 공백, 탭문자이면 무시한다(연속적으로 개행, 탭 공백이 나와도 무시한다. 즉 유효한 문자가 나올때까지 무시하고 유효한 문자부터 입력받는다)

* 표준 입출력함수는 버퍼를 공유한다(입력은 입력끼리, 출력은 출력끼리)

->scanf("%*c"); (=getchar();=fgetc(stdin);) -> 버퍼에서 하나의 문자를 읽어서 버림

 

3. 문자열 출력하기

int puts(const char *str) ->puts(배열명)

int fputs(const char *str, FILE *stream) -> fputs(배열명, stdout) 

공통점: 시작~\0까지 문자출력

차이점: put:자동으로 개행, fputs: 개행x

 

4. 문자열 연산함수(<string.h>필요)

char *strcpy(char *dest, const char *src)

->src배열에 저장된 문자열(\0 이전까지)을 복사하여 dest배열에 덮어쓴다. 그리고 끝에 널문자 \0로 마무리한다.

-> dest는 문자열(=상수) 대입불가(∵ l-vaule로 쓰이기 때문에)

 

char *strncpy(char *dest, const char *src, size_t n)

strcpy+복사할 문자 갯수지정, 단 복붙시 널문자가 붙지않는다

 

size_t strlen(const char *str) -> strlen(배열명)

널문자 이전까지의 문자의 수를 센다

 

char *strcat(char *dest, const char *src)

-> 덮어쓰기가 아닌 이어붙이기이다. dest의 \0부터 src의 글자를 붙여넣고 끝에 \0를 붙여넣는다.

 

char  *strncat(char *dest, const char *src, size_t n)

-> 정해진 문자 수만큼 이어붙이고, 끝에 \0를 붙인다(strcpy와의 차이점)

 

*아스키코드=실제숫자

 '\0'=0

 '0'=48

 

int strcmp(const char *str1, const char *str2)

-> strcmp(str1, str2)

str1>str2 일시 1반환

str1<str2 일시 -1반환

str1=str2 일시 0반환

 

* 서로다른길이의 문자열이고, 짧은 문자열의 \0와 긴문자열의 문자를 비교할 경우, \0는 0이기 때문에 긴문자열이 터크다 ex) love<lovely =>-1반환

* 아스키코드: 대문자<소문자, 실제사전: 대문자>소문자

-> 사전에선 대문자가 나중에 나옴(소문자 우선)

 

int strncmp(const char *str1, const char *str2, size_t n)

문자수를 제한해서 비교

 

'Study > 프로그래밍_언어' 카테고리의 다른 글

C언어 보충6 - 18, 19장, 추가사항  (0) 2018.02.03
C언어 보충5 - 16, 17장  (0) 2018.02.03
C언어 보충4 - 15장  (0) 2018.02.03
C언어 보충3 - 13, 14장  (0) 2018.02.02
C언어 보충1 - 10장  (0) 2017.12.02

+ Recent posts