티스토리 뷰

BackEnd/C

[13-14일차] 문자/문자열

JINSUKUKU 2021. 2. 25. 03:51

2021.02.24.수

아스키 코드

✔  알파벳과 숫자는 연속된 아스키 코드를 가지고, 소문자가 대문자보다 아스키 코드 값이 크다.

✔  제어문자도 문자를 의미하는 형식지정자 %c를 사용해 출력할 수 있다.

✔  실제로 문자는 4byte의 크기를 가지지만, 아스키 코드는 0~127의 범위를 가지므로 가장 오른쪽 1byte만 의미를 가진다.

✔  대문자 'A' 는 65, 소문자 'a' 는 97로 표현이 가능하며, 아스키 코드는 연산이 가능하므로 'A' + 32 = 'a' 가 된다.

#include <stdio.h>

int main(void){
  printf("%c + %d = %c", 'A',32,('A'-32));    //'A'    
  return 0;
}

✔ Space Bar, Tab, Enter와 같은 화이트 스페이스는 여러 값을 입력 받는 경우 구분을 위한 용도로 사용된다.

✔ 만약 형식 지정자 %c를 사용해서 입력을 받는다면, 화이트 스페이스가 문자로 저장된다.

 

 

 getchar 함수와 putchar 함수

✔  scanf()함수와 printf()함수는 형식 지정자를 사용해 여러가지 자료형의 값을 다룰 수 있다.

✔  여러 자료형을 다루므로, 문자만 입력하거나 출력하는 함수에 비해 크기가 크다.

✔  만약 문자만 입출력한다면 문자 전용 함수인 getchar() 함수와 putchar() 함수를 사용하는 것이 효율적이다.

int getchar(void);

✔ 문자 전용 입력 함수의 원형은 위와 같다.

✔ 문자 전용 입력 함수는 매개변수가 없으므로 괄호만으로 호출이 가능하다.

✔ 호출된 문자 전용 입력 함수는 입력받은 값을 아스키 코드(정수)로 반환한다.

int putchar(int);

✔ 문자 전용 출력 함수는 아스키 코드 값을 인자로 준다면 해당 문자를 출력한다.

✔ 만약 이 과정에서 에러가 발생하면 -1을 반환한다.

#include <stdio.h>

int main(void){
  char ch;
  ch = getchar();

  printf("ch : ");
  putchar(ch);
  return 0;
}

 

 

scanf 함수가 문자를 입력하는 과정

만약 문자가 입력될 때마다 메모리 공간에 데이터가 저장 혹은 수정된다면 메모리공간에 접근하는 횟수가 많아져서 비효율적이다. 그래서 우리는 입력 함수를 사용할 때에 임시 저장 공간인 Buffer를 사용한다.

 

   1. scanf() 함수의 호출.

   2. Buffer에 데이터가 있는 지 확인(비어있다면 3번, 데이터가 있으면 4번으로)

   3. Buffer가 비어있다면 문자열을 키보드로 입력받고 필요한 만큼 데이터를 가져온다.

       3-1. 키보드 입력 후 Enter를 눌러 개행하면 Buffer로 입력한 데이터가 저장

       3-2. Enter 또한 문자이므로, 개행 문자도 Buffer에 저장된다.

   4. Buffer에 데이터가 있다면 필요한 만큼 데이터를 가져온다. 
   5. 지정된 메모리 공간에 저장한다.

char ch;

//Buffer에 저장되어있는 데이터가 없으니 입력 : hi\n

scanf("%c", &ch);
printf("%c", ch);		//h 출력

scanf("%c", &ch);
printf("%c", ch);		//i 출력

scanf("%c", &ch);
printf("%c", ch);		//개행문자 출력 → 개행

✔ scanf함수가 Buffer에서 가져오는 데이터의 개수는 매개변수로 받는 형식지정자나 변수의 개수에 의해 결정된다.

✔ 개행 문자를 만나면 한 줄의 데이터가 끝났다는 의미.

✔ 이를 사용해 while문이나 for문으로 Buffer공간이 어떤식으로 사용되는 지 확인해 볼 수 있다.

✔ 명령문에 따라서 개행문자가 출력될 수도, 출력이 되지 않을 수도 있다.

#include <stdio.h>

int main(void){

  /*************************/
  //예제1. while문 사용해보기
  char ch1;
  while (1)
  {
    scanf("%c", &ch);			// 버퍼에서 한 문자 입력 받음 (hi)
    if ( ch == '\n' ) break;		// 개행문자인 경우 반복 종료
    printf("%c", ch); 			// 입력한 문자 출력
  }
  //출력 결과 : hi
  
  /*************************/
  //예제2. for문 사용해보기
  char ch2;

  for(int i=0; i<3; i++){
    scanf("%c", &ch);
    printf("%c ", ch);		
  }
  //출력 결과 : hi\n
  
  return 0;
}

 

 

 scanf ()함수의 반환 값
int scanf(const char * restrict format, ...);

✔ scanf() 함수의 원형을 살펴보면, 정수형의 반환값이 존재함을 알 수 있다.

✔ scanf() 함수는 Buffer에서 가져온 데이터의 개수를 반환한다.

✔ 만약 키보드로 ctrl + z 를 입력하면 scanf()함수는 -1 을 반환한다. (리눅스나 유닉스는 ctrl + d)

#include <stdio.h>

int main(void)
{
  char ch1, ch2, ch3, ch4;
  int test;
  printf("hello 입력 : ");
  test = scanf("%c", &ch1);
  printf("Buffer에서 가져온 데이터의 개수 : %d (%c)\n", test, ch1);

  test = scanf("%c%c", &ch1, &ch2);
  printf("Buffer에서 가져온 데이터의 개수 : %d (%c,%c)\n", test, ch1, ch2);

  test = scanf("%c%c%c", &ch1, &ch2, &ch3);
  printf("Buffer에서 가져온 데이터의 개수 : %d (%c,%c,%c)\n", test, ch1, ch2, ch3);

  //종료를 의미하는 ctrl+z 입력해 -1을 반환하도록 유도
  printf("ctrl+z 입력하면 scanf()의 반환값은 ");
  test = scanf("%c", &ch1);
  printf("%d\n", test);
}

3번째 출력부분을 통해 개행문자도 Buffer에 저장되고, 사용됨을 알 수 있다.

 

 

getchar 함수를 사용한 문자열 입력

✔  getchar 함수도 Buffer를 사용하는 문자 입력함수이다.

✔  getchar 함수를 반복 사용해 한 줄의 문자열을 char 배열에 입력할 수 있다.

#include <stdio.h>

void my_gets(char* str, int size);

int main(void)
{
	char str[7];                             // 문자열을 저장할 배열

	my_gets(str, sizeof(str));               // 한 줄의 문자열을 입력하는 함수
	printf("입력한 문자열 : %s\n", str);     // 입력한 문자열 출력

	return 0;
}


void my_gets(char* str, int size){
	int i=0;
	char ch;
	
	ch=getchar();
	
	while(1){
		if(ch=='\n' || i>size-1) break;
		str[i] = ch;
		i++;
		ch=getchar();
	}
}

 

 

 scanf 로 정수를 입력 받은 경우 개행 문자가 버퍼에 남는다
scanf("%d", &num);

1. scanf함수는 버퍼가 비어있다면 문자열을 키보드로 입력받고
2. 필요한 만큼 데이터를 가져온다
3. 가져온 데이터를 형식지정자를 확인해 필요한 자료형으로 변경하고
4. 지정된 메모리 공간에 저장한다
5. 이 때, 개행문자를 다룰 수 있는 자료형이 아닌 경우, 개행문자는 버퍼에 계속 남아있게 된다.
6. 그리고 개행문자를 다루는 형식지정자의 경우나 gets()를 사용한다면 이때에 gets는 개행문자를 가져오게된다.

 

 

fgets()와 gets()
char *fgets(char *str, int size, FILE *stream); 

✔  함수의 원형은 위와 같으며 매개변수로는 문자열의 주소와 배열의 크기 그리고 파일 스트림 방식을 받는다.

✔  문자열의 입력을 위한 함수이므로 파일 스트림 방식은 을 stdin을 사용하자.

✔  개행 문자까지 배열에 저장하고, null을 마지막 요소로 저장해 문자열을 완성

✔  만약 개행 문자 제거를 원한다면, 개행문자가 저장되어 있는 strlen(str)-1 번째 요소를 null로 초기화 하자

✔  str [ strlen str)-1 ] = '\0' ;

 

char* gets(char* str);

✔ 함수의 원형은 위와 같으며 매개변수로는 문자열의 주소를 받는다.

✔ 개행문자를 null로 인지하므로, 줄을 바꾸지 않는다.

 

버퍼 비우기
방법1.    getchar();
방법2.    scanf("%*c");
방법3.    fgetc(stdin);

표준 입력 함수는 입력 버퍼를 공유한다. 따라서 앞서 사용한 입력함수가 버퍼에 개행문자를 남긴다면 버퍼를 공유하기 때문에 이어서 개행문자를 가져와 의도치 않는 결과를 낸다. 모두 사용했다면 반드시 버퍼를 지워주자.

 

 

fputs() 와 puts()
int fputs(const char *str, FILE *stream)

✔ 함수의 원형은 위와 같으며 매개변수로는 문자열의 주소와 파일 스트림 방식을 받는다.

✔ 문자열의 출력을 위한 함수이므로 파일 스트림 방식은 stdout 을 사용하자.

✔ 문자열의 시작 위치부터 null문자가 나올 때까지 모든 문자를 출력하며 정상 출력 시 0, 실패 시 -1(EOF) 반환.

✔ 문자열을 출력한 후 자동으로 개행하지 않는다.

 

int puts(const char*str)

✔ 함수의 원형은 위와 같으며 매개변수로는 문자열의 주소를 받는다.

✔ 문자열의 시작 위치부터 null문자가 나올 때 까지 모든 문자를 출력하며 정상 출력시 0, 실패 시 -1(EOF) 반환.

✔ 문자열을 출력한 후 자동으로 개행한다.

 

 

 

 

[참고] 한빛미디어-혼자 공부하는 C언어 유튜브 강의 / 엘리스 트랙-혼자 공부하는 C언어 / 길벗-C언어 코딩 도장 / 위키백과

'BackEnd > C' 카테고리의 다른 글

[18일차] 1. 지역 변수와 전역 변수  (0) 2021.03.01
[15일차] 문자열 관련 함수의 원형  (0) 2021.02.25
[13일차] 배열과 포인터  (0) 2021.02.23
[12일차] 포인터  (0) 2021.02.23
[11일차] 함수/배열 복습  (0) 2021.02.23
댓글
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
최근에 올라온 글
글 보관함
Total
Today
Yesterday