이번 페이지 요약

코딩도장 C언어 unit 41~44

1. 문자열 관련 함수(길이, 복사, 문자열 만들기, 검색)

 

Unit 41. 문자열의 길이를 구하고 비교하기

41.1 문자열의 길이 구하기

문자열의 길이는 strlen 함수로 구할 수 있으며 string.h 헤더 파일에 선언되어 있다. 문자열 포인터와 문자 배열의 길이 모두 구할 수 있으며 사용법은 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#include <string.h>
 
int main()
{
    char *s1 = "Hello";
    char s2[10= "Hello";
 
    printf("%d\n", strlen(s1));
    printf("%d\n", strlen(s2));
    return 0;
}
cs

strlen에 문자열 포인터나 문자 배열을 넣으면 문자열의 길이가 반환된다 Hello는 5글자 이기 때문에 5가 출력되었으며 NULL 부분은 포함하지 않는다. 배열의 경우 배열의 크기는 관계없이 문자열의 길이만 구한다. 위 코드의 경우도 배열의 크기는 10이지만 출력값은 문자열의 길이인 5가 나왔다.

41.2 문자열 비교하기

strcmp 함수를 사용하면 두 문자열이 같은 지 비교할 수 있다. string.h 헤더 파일에 선언되어 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <string.h>
 
int main()
{
    char *s1 = "Hello";
    char s2[10= "Hello";
    
    int ret = strcmp(s1, s2);
 
    printf("%d\n", ret);
    return 0;
}
cs

strcmp 함수에 비교할 문자열을 넣으면 결과를 정수로 반환하며 반환 되는 값의 종류는 다음과 같다.

  • -1: ASCII 코드 기준으로 문자열2(s2)가 클 때
  • 0: ASCII 코드 기준으로 두 문자열이 같을 때
  • 1: ASCII 코드 기준으로 문자열1(s1)이 클 때

배열 문자열, 문자열 포인터 등 문자열의 저장 방식은 문자열 비교에 영향을 주지 않는다.

strcmp 함수는 문자열에서 첫 번째 문자부터 차례대로 비교하며 비교 기준은 각 문자의 ASCII 코드이다.

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
#include <string.h>
 
int main()
{
    printf("%d\n", strcmp("aaa""aaa"));
    printf("%d\n", strcmp("aab""aaa"));
    printf("%d\n", strcmp("aab""aac"));
    return 0;
}
cs

aaa는 아스키 코드로 97 97 97 이고, aab 는 97 97 98 이기 때문에 aab 가 더 크다. 또한 aac는 97 97 99 이므로 aac가 aab 보다 크다. 앞의 것이 크면 1, 뒤의 것이 크면 -1을 반환한다. 이것은 윈도우 기준이고, 리눅스나 OS X에서는 코드값의 차이를 반환한다. 따라서 입력받는 두 문자열의 크기를 비교할 땐 윈도우에서는 switch문을 사용하면 되고, 리눅스나 OS X 에서는 if 문을 사용해야 한다.

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
#include <stdio.h>
#include <string.h>
 
int main()
{
    char s1[20];
    char s2[20];
 
    printf("문자열 두 개를 입력하세요 : ");
    scanf("%s %s", s1, s2);
 
    int ret = strcmp(s1, s2);
    printf("반환값 : %d\n", ret);
 
    if(ret == 0)
    {
        printf("같음\n");
    }
    else if(ret > 0)
    {
        printf("%s가 %s보다 큼\n", s2, s1);
    }
    else if(ret < 0)
    {
        printf("%s가 %s보다 큼\n", s1, s2);
    }
 
    return 0;
}
cs

리눅스나 OS X에서 strcmp는 문자열1에서 문자열 2의 아스키 코드값을 뺏을 때 양수가 나오면 1이 크고, 음수가 나오면 2가 크다. 두 문자열이 같으면 0이 나온다.

41.3 퀴즈

정답은 c 이다.

정답은 c,d,f 이다.

41.4 연습문제 : 문자열 길이 구하기

정답은 strlen(s1) 이다.

41.5 연습문제 : 문자열 비교하기

정답은 char *s1 = "Pachelbel Canon"; 이다.

41.6 심사문제 : 문자열 길이 구하기

정답은 다음 코드와 같다.

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
#include <string.h>
 
int main()
{
    char s[30];
    scanf("%s", s);
    printf("%d", strlen(s));
    return 0;
}
cs

41.7 심사문제 : 문자열 비교하기

정답은 다음 코드와 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <string.h>
 
int main()
{
    char s1[30];
    char s2[30];
    
    scanf("%s %s", s1, s2);
    
    printf("%d", strcmp(s1, s2));
    return 0;
}
cs

Unit 42. 문자열을 복사하고 붙이기

42.1 문자열 복사하기

strcpy 함수를 이용하여 문자열을 다른 배열이나 포인터(메모리)로 복사할 수 있다. string.h 헤더 파일에 선언되어 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#define _CRT_SECURE_NO_WARNINGS    // strcpy 보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>
#include <string.h>
 
int main()
{
    char s1[10= "Hello";
    char s2[10];
 
    strcpy(s2, s1);
 
    printf("%s\n", s2);
    return 0;
}
cs

배열 s2에는 아무것도 들어있지 않았지만 strcpy 함수로 s1의 문자열이 복사되어 s2에도 저장되었다.

복사된 결과가 저장된 배열의 크기는 반드시 NULL까지 들어갈 수 있는 크기여야 한다. 따라서 Hello 라는 문자열이 복사되려면 NULL문자까지 크기는 최소 6 이상이 되어야 한다.

문자열 포인터는 복사할 공간도 없으며 읽기만 가능하기 때문에 문자열을 복사할 수 없다. 문자열 포인터에 문자열을 복사하려면 다음과 같이 메모리를 할당한 뒤 복사해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#define _CRT_SECURE_NO_WARNINGS    // strcpy 보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
int main()
{
    char *s1 = "Hello";
    char *s2 = malloc(sizeof(char* 10);
 
    strcpy(s2, s1);
 
    printf("%s\n", s2);
    free(s2);
    return 0;
}
cs

s2에 char 10개 크기만큼 동적 메모리를 할당하여 문자열을 복사하고, free로 할당한 메모리를 해제하였다.

42.2 문자열 붙이기

문자열은 strcat 함수를 이용하여 서로 붙일 수 있다. string.h 헤더파일에 선언되어 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#define _CRT_SECURE_NO_WARNINGS    // strcat 보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>
#include <string.h>
 
int main()
{
    char s1[10= "world";
    char s2[20= "Hello";
 
    strcat(s2, s1);
 
    printf("%s\n", s2);
    return 0;
}
cs

strcat함수에 최종 결과가 나올 문자열과 붙일 문자열을 넣는다. 위의 경우 s2 뒤에 s1 이 붙어서 Helloworld가 나온다.

문자열을 붙이더라도 배열이 모자라지 않도록 최종 결과가 나올 문자열의 배열 크기를 넉넉하게 만들어야 한다.

문자열 포인터에 사용하려면 붙일 문자열 포인터에 동적 메모리를 할당해 줘야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#define _CRT_SECURE_NO_WARNINGS  
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
int main()
{
    char *s1 = "world";
    char *s2 = malloc(sizeof(char* 20);
 
    strcpy(s2, "Hello");
    strcat(s2, s1);
 
    printf("%s\n", s2);
    free(s2);
    return 0;
}
cs

최종 결과가 나올 문자열 포인터에 char 20개 크기만큼 동적 메모리를 할당하고, 메모리가 할당된 문자열 포인터는 문자열을 직접 할당할 수 없으므로 strcpy 함수를 이용하여 "Hello"를 복사하고, s2 뒤에 s1을 붙인다. 문자열 사용이 끝났으면 free로 동적 메모리를 해제한다.

42.3 배열 형태의 문자열을 문자열 포인터에 복사하기

다음과 같이 배열 형태의 문자열을 문자열 포인터로 복사할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#define _CRT_SECURE_NO_WARNINGS  
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
int main()
{
    char s1[10= "Hello";
    char *s2 = malloc(sizeof(char* 10);
 
    strcpy(s2, s1);
 
    printf("%s\n", s2);
    free(s2);
    return 0;
}
cs

malloc 함수로 s2에 메모리를 복사할 문자열이 충분히 들어갈 수 있을 정도로 할당하고, strcpy로 복사하면 된다.

42.4 배열 형태의 문자열을 문자열 포인터에 붙이기

다음과 같이 배열 문자열을 문자열 포인터에 붙일 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#define _CRT_SECURE_NO_WARNINGS   
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
int main()
{
    char s1[10= "world";
    char *s2 = malloc(sizeof(char* 20);
 
    strcpy(s2, "Hello");
    strcat(s2, s1);
 
    printf("%s\n", s2);
    free(s2);
    return 0;
}
cs

문자열 포인터 s2 뒤에 문자열을 붙여야 하므로 메모리가 부족하지 않도록 넉넉히 할당하고, strcpy함수로 s2에 "Hello"를 복사한다. 이후 s2 뒤에 strcat 함수로 문자열 배열 s1을 붙이면 된다. 문자열 사용이 끝나면 free로 메모리를 해제해줘야 한다.

42.5 퀴즈

정답은 NULL문자까지 6이다.

정답은 NULL문자까지 11바이트 이다.

정답은 c 이다.

42.6 연습문제 : 문자열 포인터를 배열에 복사하기

문자열을 복사하는 것이므로 strcpy 함수를 사용하여 정답은 strcpy(s2, s1); 이다.

42.7 연습문제 : 문자열 포인터를 동적 메모리에 복사하기

정답은 다음 코드와 같다.

1. malloc(sizeof(char) * 20);

2. strcpy(s2, s1);

42.8 연습문제 : 문자 배열을 붙이기

정답은 strcat(s2, s1); 이다.

42.9 연습문제 : 문자열 리터럴과 동적 메모리 붙이기

정답은 다음 코드와 같다.

1. strcpy(s2, "Alice in");

2. strcat(s2, s1);

42.10 심사문제 : 문자 배열 복사하기

정답은 다음 코드와 같다.

scanf("%s", s1);
strcpy(s2, s1);

s1에는 값을 입력받고, s2에는 s1의 값을 복사해서 가져왔다.

42.11 심사문제 : 두 문자열 붙이기

scanf("%s", s1);
strcat(s1, "th");

문자열을 입력받아 strcat 함수로 문자열 끝에 th를 붙였다.

Unit 43. 문자열 만들기

43.1 서식을 지정하여 배열 형태로 문자열 만들기

sprintf 함수를 사용하면 서식을 지정하여 문자열을 만들 수 있다. sprintf(배열, 서식, 값);의 형태로 사용하며 서식에 값이 들어간 것을 배열에 저장할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
#define _CRT_SECURE_NO_WARNINGS    // sprintf 보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>
 
int main()
{
    char s1[20];
 
    sprintf(s1, "Hello %s""world!");
 
    printf("%s\n", s1);
    return 0;
}
cs

sprintf 함수에 문자열을 저장할 배열과 문자열을 만들 서식, 문자열을 만들 값(문자열)을 순서대로 넣어 %s부분이 "word!"로 바뀌게 된다. 위 코드에서 s1과 같이 문자열을 저장할 빈 배열을 버퍼(buffer)라고 부른다. 서식지정자로 C언어의 다양한 자료형들을 문자열로 만들 수 있다.

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
 
int main()
{
    char s1[30];
 
    sprintf(s1, "%c %d %f %e"'a'103.2f, 1.123456e-21f);
    printf("%s\n", s1);
    return 0;
}
cs

sprintf()함수에 %c, %d, %f, %e를 지정하여 각 서식지정자에 맞는 문자, 정수, 소수점 표기 실수, 지수 표기법 실수를 넣었다. 위 코드에서는 함수에 값을 바로 넣었지만, 변수를 넣어도 된다.

43.2 서식을 지정하여 문자열 포인터에 문자열 만들기

문자열 포인터를 사용하려면 malloc 함수로 메모리를 할당한 뒤 sprintf함수로 문자열을 만들면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#include <stdlib.h>
 
int main()
{
    char *s1 = malloc(sizeof(char* 20);
    sprintf(s1, "Hello, %s""world!");
    
    printf("%s\n", s1);
    free(s1);
    return 0;
}
cs

char 20개 크기의 동적 메모리를 할당하고 sprintf함수에 서식을 지정하여 문자열을 만들면 된다. 배열과 마찬가지로 문자열을 생성할 메모리 공간은 버퍼이다. 문자열 사용이 끝나면 free 함수 동적 할당한 메모리를 해제 해야 한다.

다음과 같이 다양한 종류의 서식지정자를 사용하여 다양한 자료형도 문자열로 만들 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#include <stdlib.h>
 
int main()
{
    char *s1 = malloc(sizeof(char* 30);
    sprintf(s1, "%c %d %f %e"'a'103.1f, 1.23e-23f);
    
    printf("%s\n", s1);
    free(s1);
    return 0;
}
cs

char 30개 크기만큼 동적으로 메모리를 할당하고, sprintf함수에 서식을 지정하여 문자, 정수, 소수점 표기 실수, 지수 표기 실수를 문자열로 만들었다. 문자열 사용이 끝나면 free함수로 할당한 메모리를 해제해야 한다.

43.3 퀴즈

정답은 d이다.

정답은 "%c %d" 이다.

정답은 버퍼 이다.

43.4 연습문제 : 숫자와 문자열을 조합하여 문자열 만들기

숫자와 문자열이 순서대로 들어가므로 정답은 9, "Symphony" 이다.

43.5 연습문제 : 서식에 맞게 문자열 만들기

정수 3개 ,문자 1개 정수 1개가 순서대로 들어가므로 정답은 "%d %d %d %c %d" 이다.

43.6 심사문제 : 서수 줄임말 문자열 만들기

정답은 다음코드와 같다.

scanf("%d %s", &number, name);

if(number == 1)
    sprintf(result, "%dst %s", number, name);
else if(number == 2)
    sprintf(result, "%dnd %s", number, name);
else if(number == 3)
    sprintf(result, "%drd %s", number, name);
else
    sprintf(result, "%dth %s", number, name);

숫자에 따라 숫자 뒤에 붙는것이 다르기 때문에 if 조건문을 사용하여 조건에 맞게 출력하도록 하였다.

Unit 44. 문자열 검색하기

44.1 문자열 안에서 문자로 검색하기

strchr 함수를 사용하여 문자열에서 특정 문자로 검색할 수 있다. string.h 헤더 파일에 선언되어 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <string.h>
 
int main()
{
    char s1[30= "A Garden Diary";
    char *ptr = strchr(s1, 'a');
 
    while(ptr != NULL)
    {
        printf("%s\n", ptr);
        ptr = strchr(ptr + 1'a');
    }
    return 0;
}
cs

strchr 함수에 문자열과 검색할 문자를 넣어주면 해당 문자로 시작하는 문자열의 위치(포인터)를 반환한다.

'a' 로 시작하는 부분을 더 찾기 위해 while 반복문을 사용하여 검색된 문자여릐 포인터에 1을 더해 다음부터 또 검색해서 찾는다. NULL이 나오면 검색할 문자열이 없는 것이므로 반복을 끝낸다.

'a' 가 들어간 문자를 처음 찾으면 arden Diary를 찾을 수 있다. 포인터에 1을 더하면 rden Diary 가 되므로 다음번 a를 찾을 수 있게 된다.

strchr 함수는 대소문자를 구분하므로 A는 찾지 않고 넘어간다.

44.2 문자열의 오른쪽 끝부터 문자로 검색하기

strrchr 함수는 문자열의 끝에서 부터 문자를 검색한다. string.h 헤더 파일에 선언되어 있다.

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <string.h>
 
int main()
{
    char s1[30= "A Garden Diary";
    char *ptr = strrchr(s1, 'a');
 
    printf("%s\n", ptr);
    return 0;
}
cs

strrchr 함수에 문자열과 검색할 문자를 넣으면 문자열 끝에서 부터 검색하여 'a'로 시작하는 문자열의 포인터를 반환한다. strrchr함수도 대소문자를 구분한다.

44.3 문자열 안에서 문자열로 검색하기

strstr 함수는 문자열 안에서 문자열을 검색할 수 있는 함수이며 string.h 헤더 파일에 선언되어 있다.

워드나 메모장에서 검색할 때 단어로 검색하는 경우가 많은것처럼 프로그램을 만들때도 문자열 찾는 함수를 더 많이 사용한다.

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <string.h>
 
int main()
{
    char s1[30= "A Garden Diary";
    char *ptr = strstr(s1, "den");
 
    printf("%s\n", ptr);
    return 0;
}
cs

strstr 함수에 검색할 문자열을 넣으면 해당 문자열로 시작하는 문자열의 위치(포인터)를 반환한다. 검색한 문자만 나오지 않고, 검색한 문자를 포함하여 뒤에 오는 모든 문자열이 나온다. strstr 함수도 대소문자를 구분하며 다음과 같이 반복문을 사용하여 문자열을 계속 검색할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <string.h>
 
int main()
{
    char s1[100= "A Garden Diary A Garden Diary A Garden Diary";
    char *ptr = strstr(s1, "den");
 
    while(ptr != NULL)
    {
        printf("%s\n", ptr);
        ptr = strstr(ptr+1"den");
    }
    return 0;
}
cs

44.4 퀴즈

정답은 c, e 이다.

정답은 b 이다.

44.5 연습문제 : 문자열 안에서 문자로 검색하기

정답은 다음 코드와 같다.

1. char *ptr = strchr(s1, 'n');

2. while(ptr != NULL)

3. ptr = strchr(ptr + 1, 'n');

44.6 연습문제 : 문자열의 오른쪽 끝 부터 문자로 검색하기

정답은 char *ptr = strrchr(s1, 'i'); 이다. 마지막의 ince만 출력하려면 오른쪽 부터 검색하는 strrchr 함수를 사용해야 한다.

44.7 심사문제 : 공백 개수 세기

정답은 다음 코드와 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <string.h>
 
int main()
{
    char str[1001];
    scanf("%[^\n]s", str);
    char *ptr = strchr(str, ' ');
    int cnt = 0;
    
    while(ptr != NULL)
    {
        cnt++;
        ptr = strchr(ptr + 1' ');
    }
    printf("%d\n", cnt);
    return 0;
}
cs

정수형 변수를 선언한 후 공백을 찾을 때 마다 1씩 누적하고 반복문이 끝난 뒤 누적한 값을 출력하였다.

 

+ Recent posts