이번 페이지 요약 :
코딩도장 C언어 Unit 39, 40
1. 문자열 사용하기
2. 입력값 문자열에 저장
Unit 39. 문자열 사용하기
c언어 문자를 저장하는 자료형은 있지만 문자열을 저장하는 자료형은 없다. 그래서 char 자료형에 문자열을 저장하면 컴파일은 되지만 실행은 되지 않는다. 컴파일을 한 뒤 디버깅 모드로 보면 다음과 같은 에러가 발생한다.
39.1 문자와 문자열 포인터 알아보기
문자열은 다음과 같이 char 포인터 형식으로 사용한다.
1
2
3
4
5
6
7
8
9
10
11
|
#include <stdio.h>
int main()
{
char c1 = 'a';
char *s1 = "Hello";
printf("%c\n", c1);
printf("%s\n", s1);
return 0;
}
|
cs |
문자는 글자가 하나만 있는 상태이고, 문자열은 글자 여러 개가 계속 이어진 상태를 의미한다. 문자는 1바이트 크기라 char에 저장할 수있지만, 문자열은 1바이트가 넘어서므로 char에 저장할 수 없다. 따라서 문자열은 변수에 직접 저장하지 않고 포인터를 이용하여 저장한다. 포인터는 메모리 주소를 저장하기 때문에 메모리 주소를 보고 문자열이 저장된 위치로 이동한다. 문자열 리터럴이 있는 메모리 주소는 읽기 전용이기 때문에 다른 문자열을 덮어 쓸 수 없다. 문자열 리터럴이 저장되는 위치는 컴파일러가 결정한다.
문자열은 ""(큰따옴표)로 묶어야 하며 문자열을 출력할 때는 서식지정자 %s를 사용해야 한다.
C에서 문자열은 마지막 끝에 항상 널문자가 붙는다. NULL은 0으로 표현할 수 있으며 문자열의 끝을 나타낸다.
문자열을 출력할때는 문자들을 순서대로 계속 출력하다가 NULL을 만나면 출력을 끝낸다.
39.2 문자열 포인터에서 인덱스로 문자에 접근하기
문자열도 다음과 같이 대괄호를 사용하여 인덱스로 접근할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
|
#include <stdio.h>
int main()
{
char *s1 = "Hello";
printf("%c\n", s1[1]);
printf("%c\n", s1[4]);
printf("%c\n", s1[5]);
return 0;
}
|
cs |
문자 하나를 출력할 때는 %c 서식지정자를 사용하며 맨 뒤 문자열인 5번째 인덱스를 가져오면 NULL 이기 때문에 출력해도 화면에 표시되지 않는다.
문자열 포인터에서 인덱스로 문자를 가져오는 것은 가능하지만 인덱스로 문자를 할당하는것은 불가능하다. 문자를 할당하려고 에러가 발생한다. 문자열 리터럴이 있는 메모리 주소는 읽기 전용이기 때문이다.
38.3 배열 형태로 문자열 선언하기
문자열은 다음과 같이 문자 배열에 저장할 수 도 있다.
1
2
3
4
5
6
7
8
9
|
#include <stdio.h>
int main()
{
char s1[10] = "Hello";
printf("%s\n", s1);
return 0;
}
|
cs |
위 코드는 크기가 10인 배열을 선언한 뒤 문자열을 할당한 것이다.
문자열에 배열을 저장하는 방식은 배열 요소 하나하나에 문자가 저장된다. 배열이기 때문에 인덱스는 0부터 시작하고, 문자열의 맨 뒤에 NULL이 들어간다. 남는 공간에도 모두 NULL이 들어간다.
배열로 문자열을 사용할 때는 무조건 배열을 선언한 즉시 문자열로 초기화해야 한다. 이미 선언한 배열에는 문자열을 할당할 수 없으며 정 할당하고 싶으면 요소에 문자 하나 하나를 넣으면 된다.
배열을 선언할 때는 배열의 크기를 할당할 문자열보다 크게 지정해야 한다. 문자열 문자 개수보다 배열의 크기가 작다면 컴파일은 되지만 문자열이 제대로 출력되지 않는다. 문자열은 마지막에 NULL이 꼭 들어가야 하므로 문자 개수에 하나 더한 크기가 문자열을 저장할 수 있는 배열의 최소 크기 이다.
다음과 같이 문자열을 바로 할당할 때는 배열의 크기를 생략할 수 있다.
1
2
3
4
5
6
7
8
9
|
#include <stdio.h>
int main()
{
char s1[] = "Hello";
printf("%s\n", s1);
return 0;
}
|
cs |
이와 같은 경우 배열의 크기는 문자열의 문자 개수에 맞게 자동으로 지정된다. 위 경우 문자 5개에 NULL을 더해 6이 된다.
39.4 배열 형태의 문자열에서 인덱스로 문자에 접근하기
다음과 같이 인덱스로 접근할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
|
#include <stdio.h>
int main()
{
char s1[] = "Hello";
printf("%c\n", s1[1]);
printf("%c\n", s1[4]);
printf("%c\n", s1[5]);
return 0;
}
|
cs |
배열을 인덱스로 접근하면 char과 같기 때문에 %c로 출력할 수 있다. 배열로 저장된 문자열 맨 뒤에는 NULL이 있어 출력값에는 보이지 않는다.
배열 형태의 문자열은 다음과 같이 인덱스로 접근하여 문자를 할당할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
|
#include <stdio.h>
int main()
{
char s1[] = "Hello";
s1[0] = 'A';
printf("%s\n", s1);
return 0;
}
|
cs |
Hello 가 들어있는 문자 배열의 0번 인덱스에 A를 할당해서 Aello가 되었다. 배열 형태의 문자열은 배열에 문자열이 모두 복사되었기 때문에 인덱스로 접근하여 내용을 변경할 수 있다.
39.5 퀴즈
정답은 b,e,g,h이다.
정답은 d 이다.
정답은 b 이다.
정답은 a, d 이다.
39.6 연습문제 : 문자열 만들기
정답은 char s1[] 이다.
39.7 연습문제 : 문자열 요소 출력
정답은 s1[10] 이다.
39.8 심사문제 : 문자열 만들기
정답은 다음 코드와 같다.
char s1[] = "Beethoven\n9th\nSymphony";
출력에 줄바꿈이 있으므로 개행문자 \n을 사용했다.
Unit 40. 입력 값을 문자열에 저장하기
40.1 입력 값을 배열 형태의 문자열에 저장하기
scanf 함수에서 서식지정자 %s를 사용하면 입력값을 배열 형태의 문자열에 저장할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
|
#include <stdio.h>
int main()
{
char s1[10];
printf("문자열을 입력하세요 : ");
scanf("%s", s1);
printf("%s\n", s1);
return 0;
}
|
cs |
scanf 함수에 서식지정자로 %s를 넣어서 문자열을 입력받을 수 있다. 매개변수는 입력값을 저장할 배열을 넣는데, 배열 앞에는 일반 변수와 달리 &를 붙이지 않는다. 위 코드에서는 크기가 10인 배열을 선언했으므로 문자열 맨 뒤에 붙는 널문자 까지 포함하여 총 10개의 문자를 저장할 수 있다. 따라서 실제 저장할 수 있는 문자는 9개이다.
scanf에서 %s로 문자열을 저장할 때 입력된 문자열에 공백이 있다면 배열에는 공백 직전까지만 저장된다. 공백을 포함하여 저장하고 싶다면 서식지정자로 %[^\n]s를 사용하면 된다.
40.2 입력 값을 문자열 포인터에 저장하기
문자열 포인터를 선언한 뒤 scanf 함수로 입력 값을 문자열 포인터에 저장하고 실행하면 에러가 발생한다. 이미 할당된 문자열 포인터에 저장된 메모리 주소는 읽기만 할 수 있고, 쓰기가 막혀있기 때문이다.
입력값을 문자열 포인터에 저장하려면 문자열이 들어갈 공간을 따로 만들어야 한다. malloc 함수로 메모리를 할당한 뒤 문자열을 저장하면 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *s1 = malloc(sizeof(char) * 10);
printf("문자열을 입력하세요 : ");
scanf("%s", s1);
printf("%s\n", s1);
free(s1);
return 0;
}
|
cs |
char 10개 크기 만큼 동적 메모리를 할당하여 입력값을 문자열 포인터 s1에 저장할 수 있다. 입력 받을 때 s1은 포인터이므로 &를 붙이지 않는다. 문자열 사용이 끝나면 free 함수로 메모리를 해제해야 한다. 문자열 중간에 공백이 있다면 문자열 포인터에는 공백 직전까지만 저장된다.
40.3 문자열을 여러 개 입력받기
다음과 같이 공백으로 구분된 문자열 여러개를 입력받을 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#include <stdio.h>
int main()
{
char s1[10];
char s2[10];
printf("문자열을 두 개 입력하세요 : ");
scanf("%s %s", s1, s2);
printf("%s\n", s1);
printf("%s\n", s2);
return 0;
}
|
cs |
문자열 두 개를 저장하기 위한 공간을 선언하고, scanf 함수에서 서식지정자로 %s를 두 개 넣어준다. 문자열이 저장될 배열을 두 개 넣어주면 공백으로 구분된 문자열을 입력받을 수 있다. 문자열을 더 입력받고 싶으면 %s와 입력받을 배열(또는 문자열 포인터)의 개수를 늘려주면 된다.
40.4 퀴즈
정답은 c, e, g 이다.
정답은 9 이다.
40.5 연습문제 : 입력받은 문자열을 배열에 저장하기
정답은 scanf("%s", s1); 이다.
40.6 연습문제 : 입력받은 문자열을 동적 메모리에 저장하기
정답은 다음 코드와 같다.
1. char *s1 = malloc(sizeof(char) * 10);
2. scanf("%s", s1);
40.7 연습문제 : 문자열 세 개 입력받기
정답은 scanf("%s %s %s", s1, s2, s3); 이다.
40.8 심사문제 : 문자열 4 개 입력받기
정답은 다음 코드와 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#include <stdio.h>
int main()
{
char s1[30];
char s2[30];
char s3[30];
char s4[30];
scanf("%s %s %s %s", s1, s2, s3, s4);
printf("%s\n%s\n%s\n%s\n", s1, s2, s3, s4);
return 0;
}
|
cs |
'Project H4C Study Group' 카테고리의 다른 글
[Project H4C] C언어 코딩도장(11) (0) | 2021.03.11 |
---|---|
[Project H4C] C언어 코딩도장(10) (0) | 2021.03.10 |
[Project H4C] 우리집에 GDB 있는데… 메모리 보고갈래? (3) Write-up (0) | 2021.03.09 |
[Project H4C] 우리집에 GDB 있는데… 메모리 보고갈래? (2) Write-up (0) | 2021.03.09 |
[Project H4C] 우리집에 GDB 있는데… 메모리 보고갈래? (1) Write-up (0) | 2021.03.08 |