상세 컨텐츠

본문 제목

6일차 학습내용_C언어 문자열

풀스텍과정

by 정태웅 2024. 5. 17. 09:13

본문

문자열

문자열은 " "(큰따옴표)로 묶으며 char 포인터나 배열에 저장하여 사용합니다.

char *s1 = "Hello, world!";       // char 포인터에 문자열의 메모리 주소를 저장
char s2[20] = "Hello, world!";    // char 배열에 문자열 저장
char s3[] = "Hello, world!";      // char 배열에 문자열 저장(배열의 크기 생략)

문자열을 인덱스로 접근하면 문자를 출력할 수 있습니다.

// 문자열을 인덱스로 접근
printf("%c\n", s1[0]);    // H
printf("%c\n", s2[4]);    // o

이미 선언된 배열에는 문자열을 할당할 수 없습니다.

char s1[20];

s1 = "Hello, world";    // 컴파일 에러

문자열 포인터와 문자 배열의 요소 변경

문자열 포인터에 문자열 리터럴을 할당한 뒤에는 인덱스로 접근하여 문자(요소)를 변경할 수 없습니다(문자열 리터럴이 있는 메모리 주소는 읽기 전용). 하지만 문자 배열은 인덱스로 접근하여 문자를 변경할 수 있습니다(배열에 문자열이 복사됨).

char *s1 = "Hello";       // 문자열 포인터에 문자열 리터럴 할당(읽기 전용 메모리를 가리킴)
s1[0] = 'A';              // 실행 에러: 문자를 변경할 수 없음

char s2[10] = "Hello";    // 문자 배열에 문자열 리터럴 할당(배열에 문자열이 복사됨)
s1[0] = 'A';              // 문자를 변경할 수 있음

입력된 문자열을 배열 또는 포인터에 저장하기

입력된 문자열을 배열에 저장할 때는 scanf 함수를 사용하며 배열 앞에는 &를 붙이지 않습니다.

char s1[10];        // 크기가 10인 char형 배열을 선언

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

입력된 문자열을 포인터에 저장할 때도 포인터 앞에는 &를 붙이지 않습니다.

char *s1 = malloc(sizeof(char) * 10);    // char 10개 크기만큼 동적 메모리 할당

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

free(s1);    // 동적 메모리 해제

문자열과 서식 지정자

문자열은 서식 지정자 %s를 사용합니다.

char s1[20];
scanf("%s", s1);     // %s로 문자열을 입력받음
printf("%s", s1);    // %s로 문자열을 출력

scanf로 공백까지 포함하여 문자열을 입력받으려면 서식 지정자로 "%[^\n]s"를 사용합니다.

char s1[30];
scanf("%[^\n]s", s1);    // 공백까지 포함하여 문자열 입력받기

문자열과 NULL

문자열은 문자열의 끝나는 지점을 알려주기 위해 마지막에 NULL(\0)이 붙습니다. 만약 배열이라면 NULL까지 들어가야 하므로 배열의 크기는 문자열의 길이보다 1이 더 커야 합니다.

char s1[6] = "Hello";    // 5글자 + NULL이므로 배열의 최소 크기는 6이상

문자열 함수

다음은 문자열 함수의 매개변수, 반환값과 설명을 정리한 표입니다.

 문자열 함수
함수헤더 파일설명
strlen(문자열포인터);
strlen(문자배열);
string.h 문자열의 길이를 구합니다(NULL은 포함하지 않음).
strcmp(문자열1, 문자열2); string.h 문자열1과 문자열2를 비교합니다(Windows).
  • -1: ASCII 코드 기준으로 문자열2가 클 때
  • 0: ASCII 코드 기준으로 두 문자열이 같을 때
  • 1: ASCII 코드 기존으로 문자열1이 클 때
    앞에 것이 크면 1, 뒤에 것이 크면 -1입니다.

리눅스와 OS X에서는 문자열1의 ASCII 코드값에서 문자열2의 ASCII 코드값을 뺀 결과를 반환합니다.
  • 반환값이 양수가 나오면 문자열1이 크고, 음수가 나오면 문자열2가 큼
  • ASCII 코드 기준으로 두 문자열이 같으면 0
strcpy(대상문자열, 원본문자열); string.h 문자열을 복사합니다.
strcat(최종문자열, 붙일문자열); string.h 문자열을 붙입니다.
sprintf(배열, 서식, 값);
sprintf(배열, 서식, 값1, 값2, ...);
sprintf(문자열포인터, 서식, 값);
sprintf(문자열포인터, 서식, 값1, 값2, ...);
stdio.h 서식을 지정하여 문자열을 생성합니다.





strchr(문자열, 검색할문자); string.h 문자열 안에서 문자로 검색합니다. 문자를 찾았으면
해당 문자부터 NULL 바로 앞까지의 문자열이 나옵니다
(해당 문자의 포인터 반환).
strrchr(문자열, 검색할문자); string.h 문자열의 뒤에서부터 문자로 검색합니다. 문자를
찾았으면 해당 문자부터 NULL 바로 앞까지의
문자열이 나옵니다(해당 문자의 포인터 반환).
strstr(대상문자열, 검색할문자열); string.h 문자열 안에서 문자열로 검색합니다. 문자열을
찾았으면 해당 문자열부터 NULL 바로 앞까지의
문자열이 나옵니다(해당 문자열의 포인터 반환).
strtok(대상문자열, 기준문자); string.h 문자를 기준으로 문자열을 자릅니다. 자른
문자열을 한 번에 얻을 수 없으므로 while
계속 반복 사용해야 합니다. 그리고 문자열을
자른 부분은 NULL로 바뀝니다.
atoi(문자열); stdlib.h 문자열을 정수로 변환합니다.
atof(문자열); stdlib.h 문자열을 실수로 변환합니다.
strtol(문자열, 끝포인터, 진법); stdlib.h 특정 진법으로 표기된 문자열을 정수로 변환
합니다. 정수 여러 개가 들어있는 문자열을
변환할 수 있습니다.
strtof(문자열, 끝포인터); stdlib.h 문자열을 실수로 변환합니다. 실수 여러 개가
들어있는 문자열을 변환할 수 있습니다.
sprintf(문자열,"%d", 정수);
sprintf(문자열,"%x", 정수);
sprintf(문자열,"%X", 정수);
stdio.h 정수를 문자열로 변환합니다.
  • %d: 10진수
  • %x: 16진수 소문자
  • %X: 16진수 대문자
sprintf(문자열,"%f", 실수); stdio.h 실수를 문자열로 변환합니다.

typedef로 자료형의 별칭 정의하기

typedef를 사용하면 구조체를 포함하여 모든 자료형의 별칭을 정의할 수 있습니다.

typedef 자료형 별칭;     // 자료형의 별칭 정의
typedef 자료형* 별칭;    // 자료형 포인터의 별칭 정의

구조체

구조체는 struct 키워드로 정의하며 관련 정보를 하나의 의미로 묶을 때 사용합니다.

// 구조체 정의하기
struct 구조체이름 {
    자료형 멤버이름;
};

// 구조체 변수 선언하기
struct 구조체이름 변수이름;

// 구조체 변수를 선언하는 동시에 값을 초기화
struct 구조체이름 변수이름 = { .멤버이름1 = 값1, .멤버이름2 = 값2 };
struct 구조체이름 변수이름 = { 값1, 값2 };

// 구조체를 정의하는 동시에 변수 선언하기
struct 구조체이름 {
    자료형 멤버이름;
} 변수;

// 구조체를 정의하면서 구조체 별칭 정의하기
typedef struct 구조체이름 {
    자료형 멤버이름;
} 구조체별칭;

// 익명 구조체 정의하기
typedef struct {
    자료형 멤버이름;
} 구조체별칭;

// 구조체 별칭으로 변수 선언하기
구조체별칭 변수이름;

구조체 멤버에 접근할 때는 . (점)을 사용합니다.

struct 구조체이름 변수이름;

변수.멤버;         // 구조체 멤버의 값을 가져옴
변수.멤버 = 값;    // 구조체 멤버에 값을 저장

malloc 함수로 구조체 포인터에 메모리를 할당할 수 있으며 이때는 멤버에 접근할 때 -> (화살표 연산자)를 사용합니다.

// 구조체 포인터에 동적 메모리 할당
struct 구조체이름 *포인터이름 = malloc(sizeof(struct 구조체이름));

// 구조체 별칭으로 포인터를 선언하고 동적 메모리 할당
구조체별칭 *포인터이름 = malloc(sizeof(구조체별칭));

포인터->멤버;         // 구조체 포인터 멤버의 값을 가져옴
포인터->멤버 = 값;    // 구조체 포인터 멤버에 값을 저장

free(포인터);    // 구조체 메모리 해제

구조체 포인터에는 & (주소 연산자)로 구조체 변수의 메모리 주소를 구해서 할당할 수 있습니다.

구조체포인터 = &구조체변수;

구조체 배열

구조체 변수를 선언하려면 [ ] (대괄호)에 크기를 지정합니다. 구조체 배열의 멤버에 접근하려면 [ ]에 인덱스를 지정한 뒤 .으로 접근합니다.

// 구조체 배열 선언하기
struct 구조체이름 변수이름[크기];

// 구조체 배열을 선언하는 동시에 값을 초기화
struct 구조체이름 변수이름[크기] = { { .멤버이름1 = 값1, .멤버이름2 = 값2 }, 
                                   { .멤버이름1 = 값3, .멤버이름2 = 값4 } };
struct 구조체이름 변수이름[크기] = { { 값1, 값2 }, { 값3, 값4 } };

배열[인덱스].멤버;         // 구조체 배열에서 요소의 멤버 값을 가져옴
배열[인덱스].멤버 = 값;    // 구조체 배열에서 요소의 멤버에 값을 저장

구조체 포인터 배열

구조체 포인터 배열을 선언하려면 포인터 변수 이름 뒤에 [ ]를 붙인 뒤 크기를 지정합니다. 이때 배열의 요소에는 메모리를 할당해야 하며 멤버에 접근할 때는 [ ]에 인덱스를 지정한 뒤 ->로 접근합니다.

// 구조체 포인터 배열 선언하기
struct 구조체이름 *포인터이름[크기];

// 구조체 포인터 배열에 메모리 할당하기
for (int i = 0; i < 크기; i++)                   // 배열 크기만큼 반복
{
    배열[i] = malloc(sizeof(struct 구조체));    // 각 요소에 구조체 크기만큼 메모리 할당
}

배열[인덱스]->멤버;          // 구조체 포인터 배열에서 요소의 멤버 값을 가져옴
배열[인덱스]->멤버 = 값;     // 구조체 포인터 배열에서 요소의 멤버에 값을 저장

// 구조체 포인터 배열의 메모리 해제하기
for (int i = 0; i < 크기; i++)    // 배열 크기만큼 반복
{
    free(포인터[i]);              // 각 요소의 동적 메모리 해제
}

열거형

열거형은 정수형 상수에 이름을 붙입니다. 열거형에 초깃값을 지정하지 않으면 0부터 시작합니다.

// 열거형 정의하기
enum 열거형이름 {
    값1 = 초깃값,
    값2,
    값3,
};

// 값의 개수까지 포함된 열거형 정의하기
enum 열거형이름 {
    값1 = 초깃값,
    값2,
    값3,
    열거형Count    // 값의 개수를 나타내는 항목
};

// 열거형 변수 선언하기
enum 열거형이름 변수이름;

변수 = 열거형값1;     // 열거형 변수에 열거형 값 할당

// 열거형을 정의하면서 열거형 별칭 정의하기
typedef enum 열거형이름 {
    값1 = 초깃값,
    값2,
    값3
} 열거형별칭;

// 열거형을 정의하면서 열거형 별칭 정의하기(값의 개수 포함)
typedef enum 열거형이름 {
    값1 = 초깃값,
    값2,
    값3
    열거형Count    // 값의 개수를 나타내는 항목
} 열거형별칭;

// 열거형 별칭으로 변수 선언하기
열거형별칭 변수이름;

// 열거형을 switch에 활용하기
switch (열거형변수)
{
case 열거형값1:
    코드1;
    break;
case 열거형값2:
    코드2;
    break;
}

// 열거형을 for에 활용하기
for (열거형이름 i = 열거형값1; i < 열거형Count; i++)    // 초깃값은 열거형값1, 
{                                                     // 열거형Count보다 작을 때까지 반복
    코드;
}
variable_enum_02.c
0.00MB

variable_enum_01.c
0.00MB
variable_struct_array_03.C
0.00MB
variable_struct_array_02.c
0.00MB
variable_struct_array_point_02.c
0.00MB
variable_struct_array_point_01.c
0.00MB
variable_struct_array_01.c
0.00MB
variable_struct_point_02.c
0.00MB
variable_struct_point_01.c
0.00MB
variable_struct_04.c
0.00MB
variable_struct_typedef_01.c
0.00MB
variable_struct_03.c
0.00MB
variable_struct_02.c
0.00MB
variable_struct_01.c
0.00MB
variable_char_atoi_01.c
0.00MB
variable_char_sprintf_02.c
0.00MB
variable_char_strtok_02.c
0.00MB
variable_char_strtok_01.c
0.00MB
variable_char_strcpy_03.c
0.00MB
variable_char_strchr_01.c
0.00MB
variable_char_strcpy_04.c
0.00MB
variable_char_sprintf_01.c
0.00MB
variable_char_strcat_01.c
0.00MB
variable_char_strcpy_01.c
0.00MB
variable_char_strcpy_02.c
0.00MB
variable_char_strlen_02.c
0.00MB
variable_char_strcmp_01.c
0.00MB
variable_char_strlen_01.c
0.00MB
variable_char_malloc_01.c
0.00MB
variable_char_02.c
0.00MB
variable_char_01.c
0.00MB

관련글 더보기