본문 바로가기
AI HW study/Baekjoon

백준 5단계 문자열 개념 정리

by jyun13 2023. 7. 15.

1. 문자와 문자열

- 문자와 문자열은 다른 개념입니다. 

- 문자는 단일 문자를 이야기하며, 문자열은 둘 이상의 결합문자를 이야기 합니다.

 

문자열을 표현하는 방법은 C언어에서 단 두가지 밖에 없습니다.

바로 배열과 포인터를 이용하는 방법이지요.

 

char str[]="Garbage";

 

이와 같이 초기화를 해주거나.

 

char *str="Garbage";

 

마지막에서 문자열에서 중요한것은 \0입니다. 바로 NULL문자이죠.

이 문자의 존재는 "여기서까지가 문자열이다."하고 광고하는겁니다.

예를들어 char c1[]="C language"; 라고 적으면

char c1[] = {'C', ' ', 'l', 'a', 'n', 'g', 'u', 'a', 'g', 'e', '\0'};

실제로는 아래처럼 저장이 됩니다.

널문자까지를 문자열로 읽는 컴파일러의 특성상 만약 널문자뒤에 공백 Or 다른 문자가

존재하더라도 출력시에시는 널문자까지 읽습니다. 예를들어

char c1[100] = {'C', ' ', 'l', 'a', 'n', 'g', 'u', 'a', 'g', 'e', '\0'};

의 경우 비어 있는 칸이 89칸이나 되지만

그렇다고 빈칸까지 다 인쇄 되지 않고 널문자까지 인쇄됩니다.

또한 char c1[] = {'C', ' ', 'l', 'a', 'n', 'g', 'u', 'a', 'g', 'e', '\0','J','a','v','a','\0'};

라고 쓰더라도 실제 printf("%s",c1);을 실행할경우 최초의 널문자 까지의 배열만 읽어서

C language가 출력되게 됩니다.

 

 

 

2. 문자 입력받기

- C언어에서 문자를 입력받기 위해서는 char 자료형을 이용해야 합니다.

- 서식문자로 %c를 사용합니다.

- 정수나 실수를 입력 받듯이 %c를 붙여서 입력받으면 c2값은 들어가지 않습니다. 왜냐하면 엔터키나 스페이스도 하나의 문자로 치기 때문에 c2값에는 엔터가 들어가게 되기 때문입니다.

 

int main()
{
    char c1;

    printf("문자를 입력하세요: ");
    scanf("%c", &c1);    // 문자를 입력받아서 변수에 저장

    printf("%c\n", c1);    // 변수의 내용을 출력

    return 0;
}

 

예시) scanf를 여러번 이용하여 문자 여러개 입력받기

- 이 예시도 마찬가지로 scanf 를 그냥 두번 쓰면 c2에 엔터가 들어갑니다.

- 코드 결과 

두 문자 입력: 1 3

c1 = 1, c2 =  

int main(void)
{
	char  a, b;


	printf(" 두 문자 입력 : ");
	scanf("%c", &a);
	scanf("%c", &b);

	printf(" a = %c, b = %c \n", a, b);   //b값엔 엔터가 들어감

	return 0;
}

해결방법은 두번째 scanf에서 %c앞에 공백을 넣거나, scanf사이에 getchar()를 넣어주면 됩니다.

* getchar함수는 문자열이나 문자를 입력받습니다. 따라서 scanf 사이에 써주면 getchar에 엔터가 입력받게 됩니다.

int main(void)
{
	char  a, b;


	printf(" 두 문자 입력 : ");
	scanf("%c", &a);
	getchar();
	scanf("%c", &b); //scanf(" %c",&b);

	printf(" a = %c, b = %c \n", a, b);

	return 0;
}

3. 문자열 입력받기

- 문자열을 입력받기위해서는 char형 배열을 선언해야 합니다.

- 문자열은 서식문자로 %s를 사용합니다.

- 문자열의 맨 뒤에는 null문자가 들어갑니다. 

* 배열에 "hello" 가 들어갔으면 null문자를 포함해서 배열의 크기가 6이 된다. 

 

예시) 문자열 입력받기

int main()
{
    char s1[10];    // 크기가 10인 char형 배열을 선언

    printf("문자열을 입력하세요: ");
    scanf("%s", s1);     // 표준 입력을 받아서 배열 형태의 문자열에 저장

    printf("%s\n", s1);  // 문자열의 내용을 출력

    return 0;
}

ex) 여러 문자열 입력받기

int main()
{
    char s1[5][100];    // 최대 100길이의 문자를 입력받음.

    printf("문자열을 입력하세요: ");
    for(int i=0;i<5;i++){
        scanf("%s", s1[i]);     // 표준 입력을 받아서 배열 형태의 문자열에 저장
    }
    
    for(int i=0;i<5;i++){
        printf("%s\n", s1[i]);  // 문자열의 내용을 출력
    }
    
    return 0;
}

1. scanf()

- scanf("입력서식", &변수명);

- 입력서식에 맞는 데이터를 입력받아 변수명에 저장한 후, 그 변수의 주소를 시스템에 넘겨준다.

- 공백 포함이 불가능하며, 입력이 끝났음을 알려주는 것은 'Space Bar'와 'Enter' 키이다.

- 하지만 문자열 배열의 경우에는 배열의 이름은 주소를 담고 있기 때문에 &를 안붙여도 된다.

// 전처리문
#include<stdio.h>

int main(){

   char name[10];

   printf("이름 : ");
   scanf("%s", name);   // 배열은 주소의 의미를 내포하고 있어 &name으로 쓰지 않는다.
   printf("입력한 이름은 %s 입니다.\n", name);

   return 0;
}

입력이 [홍 길동] 일때 scanf는 공백을 기준으로 자름

2. gets()

- 공백 포함이 가능하다.

// 전처리문
#include<stdio.h>

int main(){

   char name[10];

   printf("이름 : ");
   gets(name);   // 공백(space)을 포함한 문자열 입력이 가능하다.
   printf("입력한 이름은 %s 입니다.\n", name);

   return 0;
}

gets는 공백 포함이 가능해서 입력이 [홍 길동]일때도 그대로 출력된다.

 

문자열 함수 (strlen, strcmp, strcpy, strcat, strchr, strrchr/ main 함수의 인수/ 문자열을 가리키는 포인터 배열/ ren)

https://wikidocs.net/12188 

 

11-01. 문자열 처리 함수

[TOC] ## 대표적 문자열 처리 함수 헤더화일: string.h와 ctype.h * [string.h](http://www.cplusplus.com/reference/cst…

wikidocs.net

 

<문자열 길이 구하기- 방법 2>

1. 

#include <stdio.h>

int main()
{
	char ch[30];
	scanf("%s", &ch); // goorm
	
	int i;
	for(i = 0; ch[i] != NULL; i++){
		// i가 ch의 인덱스를 돌다가 NULL 값이 되면 멈추고 그 숫자를 표시해주는것
	}

	printf("%d", i); // 5

	return 0;
}

- 다른 방법으로는 for문이 돌때마다 값을 카운트해주는 변수를 지정해서 확인해도 된다.

 

2. 

#include <stdio.h>
#include <string.h> // 전처리기 <string.h> 추가

int main()
{
	char input[5] = "Love";
    printf("문자열 길이 : &d", strlen(input)); // 문자열 길이 : 4

	return 0;
}

- 전처리기 <string.h> 추가하여 strlen() 함수를 이용해서 구할 수도 있다.

 

<문자열 비교>

- 문자열 비교하는 함수: strcmp 
1. 인자 값중에 왼쪽의 값 앞에 있는 값이라면 -1
2. 인자 값중에 왼쪽의 값 뒤에 있는 값이라면 1
3. 인자 값이 둘다 동일하다면 0 이 출력

#include <stdio.h>
#include <string.h> // 전처리기 <string.h> 추가

int main()
{
	char inputOne[5] = "A";
	char inputTwo[5] = "B";
    printf("문자열 비교 : &d", strcmp(inputOne, inputTwo)); // 문자열 비교 : -1
    
	char inputOne[5] = "B";
	char inputTwo[5] = "A";
    printf("문자열 비교 : &d", strcmp(inputOne, inputTwo)); // 문자열 비교 : 1
    
	char inputOne[5] = "A";
	char inputTwo[5] = "A";
    printf("문자열 비교 : &d", strcmp(inputOne, inputTwo)); // 문자열 비교 : 0

	return 0;
}

 

 3. 다차원 배열 // 2차원 배

 

 지금까지의 배열은 갯수가 하나인 배열이었다.

이것을 '1차원 배열'이라고도 하며, 그 이상으로도 선언하고 사용이 가능합니다.

자료형 변수명 [행의 갯수][열의 갯수];

int a[2][3] = { {1, 2, 3}, {4, 5, 6} };

int i, k;

 

for (i = 0; i < 2; i++)

for (k = 0; k < 3; k++)

printf("%d\n", a[i][k]);

 

실행 결과

 

1

2

3

4

5

6

 위 예의 첫번째 줄처럼 대괄호를 하나 더 써서 선언했고,

1차원 배열에서 초기화할때의 값을 콤마 ','로 구분하여 중괄호 {}로 묶어 주었습니다.

그리고 각각 배열에 저장된 값을 출력하고 있습니다.

 

위 예의 배열 'a'는 이런 모양이라고 생각해볼 수 있습니다.

[ 1 ][ 2 ][ 3 ] // 가로 방향의 한 줄 '행' //세로 방향의 한 줄 '열'

[ 4 ][ 5 ][ 6 ]

void main()

{

char name[20][20] = {'\0'};   // 이름

char grade = '\0';                 // 등급

int scoreKOR[20] = {0};              // 국어점수

int scoreMAT[20] = {0};              // 수학점수

int scoreENG[20] = {0};              // 영어점수

int scoreSCI[20] = {0};               // 과학점수

char comment[20][200] = {'\0'};        // 평가

 

int index = 0;                         // 입력받을 배열 위치

 

...

 

 오늘 알아본 배열을 사용해서, 입력받는 부분에 사용한 변수들을 20개만큼의 배열로 선언을 해 주었습니다.

20개라는건 결국 20명까지만 입력을 받을 수 있다는 이야기입니다.

또한 초기화할때 배열은 {}를 사용해야 하므로 해 주었습니다.

뒤의 int형 변수 index는 현재 입력받아야 하는 배열의 위치를 저장하게 됩니다.

 

...

 

switch (menuChoice)

{

case '1':

{

// 사용자 입력

do

{

printf("이름을 입력하세요 : ");

scanf_s("%s", temp, sizeof(temp));

len = strlen(temp) + 1;

if (len > sizeof(name[index]))

printf("너무 긴 이름을 입력하셨습니다.\n");

else

strcpy_s(name[index], sizeof(name[index]), temp);

} while (len > sizeof(name[index]));

printf("국어점수를 입력하세요 : ");

scanf_s("%d", &scoreKOR[index]);

printf("수학점수를 입력하세요 : ");

scanf_s("%d", &scoreMAT[index]);

printf("영어점수를 입력하세요 : ");

scanf_s("%d", &scoreENG[index]);

printf("과학점수를 입력하세요 : ");

scanf_s("%d", &scoreSCI[index]);

getchar();

printf("평가를 입력하세요 : ");

gets_s(comment[index], sizeof(comment[index]));

index++;

}

 

break;

 

...

 

< 문자열 자르기 >

#define _CRT_SECURE_NO_WARNINGS    // strtok 보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>
#include <string.h>    // strtok 함수가 선언된 헤더 파일

int main()
{
    char s1[30] = "The Little Prince";  // 크기가 30인 char형 배열을 선언하고 문자열 할당

    char *ptr = strtok(s1, " ");      // " " 공백 문자를 기준으로 문자열을 자름, 포인터 반환

    while (ptr != NULL)               // 자른 문자열이 나오지 않을 때까지 반복
    {
        printf("%s\n", ptr);          // 자른 문자열 출력
        ptr = strtok(NULL, " ");      // 다음 문자열을 잘라서 포인터를 반환
    }

    return 0;
}

실행 결과

The
Little
Prince

strtok 함수는 지정된 문자를 기준으로 문자열을 자릅니다.

즉, strtok(s1, " ");와 같이 " " (공백 문자)를 넣어주면 공백으로 구분하여 문자열을 자릅니다. (단, 기준 문자를 ' '로 묶으면 안 됩니다).

특히 strtok 함수는 잘린 문자열을 한 번에 얻을 수 없어서 while 반복문으로 문자열을 계속 자르다가 문자열이 나오지 않으면 반복문을 끝내는 방식으로 사용합니다.

'AI HW study > Baekjoon' 카테고리의 다른 글

백준 9단계: 약수, 배수와 소수  (0) 2023.07.18
백준 5단계 문자열  (0) 2023.07.15
백준 4단계: 1차원 배열  (0) 2023.07.14
백준 3단계-2: 반복문  (0) 2023.07.14
백준 10단계: 기하(직사각형과 삼각형)  (0) 2023.07.14