메모리 함수 (string.h)
memcpy - 메모리 복사
#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);
src에서dest로n바이트를 복사- 메모리 영역이 겹치면 정의되지 않은 동작 (겹치면
memmove사용) - 반환값:
dest포인터
#include <stdio.h>
#include <string.h>
int main() {
char src[] = "Hello, World!";
char dest[20];
memcpy(dest, src, strlen(src) + 1); // +1은 NULL 문자 포함
printf("복사된 문자열: %s\n", dest); // "Hello, World!"
// 배열 복사
int arr1[] = {1, 2, 3, 4, 5};
int arr2[5];
memcpy(arr2, arr1, sizeof(arr1));
for (int i = 0; i < 5; i++) {
printf("%d ", arr2[i]); // 1 2 3 4 5
}
return 0;
}
memmove - 겹치는 메모리 복사
#include <string.h>
void *memmove(void *dest, const void *src, size_t n);
memcpy와 동일하지만 메모리 영역이 겹쳐도 안전- 반환값:
dest포인터
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello, World!";
// 메모리가 겹치는 경우 (str[7]부터 str[0]으로 복사)
memmove(str, str + 7, 6); // "World!"를 앞으로 이동
str[6] = '\0';
printf("%s\n", str); // "World!"
// 배열 요소 이동
int arr[] = {1, 2, 3, 4, 5};
memmove(arr + 1, arr, 4 * sizeof(int)); // 한 칸씩 오른쪽으로
arr[0] = 0;
// 결과: {0, 1, 2, 3, 4}
return 0;
}
memset - 메모리 초기화
#include <string.h>
void *memset(void *s, int c, size_t n);
- 메모리 영역을 특정 값으로 초기화
c는unsigned char로 변환되어 사용- 반환값:
s포인터
#include <stdio.h>
#include <string.h>
int main() {
char buffer[100];
// 0으로 초기화
memset(buffer, 0, sizeof(buffer));
// 특정 문자로 채우기
memset(buffer, 'A', 10);
buffer[10] = '\0';
printf("%s\n", buffer); // "AAAAAAAAAA"
// 배열 초기화
int arr[10];
memset(arr, 0, sizeof(arr)); // 모든 요소를 0으로
// -1로 초기화 (주의: int는 4바이트이므로 0xFFFFFFFF가 됨)
memset(arr, -1, sizeof(arr));
return 0;
}
memcmp - 메모리 비교
#include <string.h>
int memcmp(const void *s1, const void *s2, size_t n);
- 두 메모리 영역을 바이트 단위로 비교
- 반환값:
s1 < s2: 음수s1 == s2: 0s1 > s2: 양수
#include <stdio.h>
#include <string.h>
int main() {
char str1[] = "Hello";
char str2[] = "Hello";
char str3[] = "World";
// 문자열 비교
int result1 = memcmp(str1, str2, 5);
printf("%d\n", result1); // 0 (같음)
int result2 = memcmp(str1, str3, 5);
printf("%d\n", result2); // 음수 (str1 < str3)
// 배열 비교
int arr1[] = {1, 2, 3};
int arr2[] = {1, 2, 3};
int arr3[] = {1, 2, 4};
int cmp1 = memcmp(arr1, arr2, sizeof(arr1));
printf("%d\n", cmp1); // 0 (같음)
int cmp2 = memcmp(arr1, arr3, sizeof(arr1));
printf("%d\n", cmp2); // 음수 (arr1 < arr3)
return 0;
}
memchr - 메모리에서 문자 검색
#include <string.h>
void *memchr(const void *s, int c, size_t n);
- 메모리 영역에서 특정 문자를 검색
- 반환값: 찾으면 해당 포인터, 못 찾으면 NULL
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello, World!";
// 'W' 문자 찾기
char *found = (char *)memchr(str, 'W', strlen(str));
if (found) {
printf("찾음: %s\n", found); // "World!"
}
// 배열에서 특정 값 찾기
int arr[] = {10, 20, 30, 40, 50};
int *ptr = (int *)memchr(arr, 30, sizeof(arr));
if (ptr) {
printf("값 30을 찾았습니다: 인덱스 %ld\n", ptr - arr);
}
return 0;
}
문자열 함수 (string.h)
strlen - 문자열 길이
#include <string.h>
size_t strlen(const char *s);
- NULL 문자(
\0)를 제외한 문자열 길이 반환
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello";
printf("%zu\n", strlen(str)); // 5
char *ptr = "World";
printf("%zu\n", strlen(ptr)); // 5
return 0;
}
strcpy - 문자열 복사
#include <string.h>
char *strcpy(char *dest, const char *src);
src를dest로 복사 (NULL 문자 포함)dest는 충분한 크기여야 함- 반환값:
dest포인터
#include <stdio.h>
#include <string.h>
int main() {
char src[] = "Hello, World!";
char dest[50];
strcpy(dest, src);
printf("%s\n", dest); // "Hello, World!"
return 0;
}
strncpy - 제한된 문자열 복사
#include <string.h>
char *strncpy(char *dest, const char *src, size_t n);
- 최대
n문자까지 복사 n이src길이보다 크면 나머지는 NULL 문자로 채움- 반환값:
dest포인터
#include <stdio.h>
#include <string.h>
int main() {
char src[] = "Hello, World!";
char dest[20];
strncpy(dest, src, 5);
dest[5] = '\0'; // NULL 문자 추가 필요
printf("%s\n", dest); // "Hello"
return 0;
}
strcat - 문자열 연결
#include <string.h>
char *strcat(char *dest, const char *src);
src를dest끝에 연결dest는 충분한 크기여야 함- 반환값:
dest포인터
#include <stdio.h>
#include <string.h>
int main() {
char dest[50] = "Hello";
char src[] = ", World!";
strcat(dest, src);
printf("%s\n", dest); // "Hello, World!"
return 0;
}
strncat - 제한된 문자열 연결
#include <string.h>
char *strncat(char *dest, const char *src, size_t n);
src에서 최대n문자를dest끝에 연결- 자동으로 NULL 문자 추가
- 반환값:
dest포인터
#include <stdio.h>
#include <string.h>
int main() {
char dest[50] = "Hello";
char src[] = ", World!";
strncat(dest, src, 3); // ", W"만 추가
printf("%s\n", dest); // "Hello, W"
return 0;
}
strcmp - 문자열 비교
#include <string.h>
int strcmp(const char *s1, const char *s2);
- 두 문자열을 사전식으로 비교
- 반환값:
s1 < s2: 음수s1 == s2: 0s1 > s2: 양수
#include <stdio.h>
#include <string.h>
int main() {
char str1[] = "apple";
char str2[] = "banana";
char str3[] = "apple";
printf("%d\n", strcmp(str1, str2)); // 음수 ("apple" < "banana")
printf("%d\n", strcmp(str1, str3)); // 0 (같음)
printf("%d\n", strcmp(str2, str1)); // 양수 ("banana" > "apple")
return 0;
}
strncmp - 제한된 문자열 비교
#include <string.h>
int strncmp(const char *s1, const char *s2, size_t n);
- 최대
n문자까지만 비교
#include <stdio.h>
#include <string.h>
int main() {
char str1[] = "apple";
char str2[] = "application";
// 처음 3글자만 비교
printf("%d\n", strncmp(str1, str2, 3)); // 0 (같음: "app")
printf("%d\n", strncmp(str1, str2, 5)); // 음수 ("apple" < "appli")
return 0;
}
strchr - 문자 검색
#include <string.h>
char *strchr(const char *s, int c);
- 문자열에서 첫 번째로 나타나는 문자
c검색 - 반환값: 찾으면 해당 포인터, 못 찾으면 NULL
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello, World!";
char *found = strchr(str, 'o');
if (found) {
printf("찾음: %s\n", found); // "o, World!"
printf("인덱스: %ld\n", found - str); // 4
}
// 모든 'o' 찾기
char *ptr = str;
while ((ptr = strchr(ptr, 'o')) != NULL) {
printf("위치: %ld\n", ptr - str);
ptr++; // 다음 위치부터 검색
}
return 0;
}
strrchr - 마지막 문자 검색
#include <string.h>
char *strrchr(const char *s, int c);
- 문자열에서 마지막으로 나타나는 문자
c검색
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello, World!";
char *found = strrchr(str, 'o');
if (found) {
printf("마지막 'o' 위치: %ld\n", found - str); // 8
printf("%s\n", found); // "orld!"
}
return 0;
}
strstr - 부분 문자열 검색
#include <string.h>
char *strstr(const char *haystack, const char *needle);
haystack에서needle부분 문자열 검색- 반환값: 찾으면 해당 포인터, 못 찾으면 NULL
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello, World!";
char search[] = "World";
char *found = strstr(str, search);
if (found) {
printf("찾음: %s\n", found); // "World!"
printf("인덱스: %ld\n", found - str); // 7
}
return 0;
}
strtok - 문자열 토큰화
#include <string.h>
char *strtok(char *str, const char *delim);
- 문자열을 구분자로 분리
- 첫 번째 호출:
str전달 - 이후 호출: NULL 전달 (이전 문자열 계속 사용)
- 반환값: 토큰 포인터, 더 이상 없으면 NULL
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "apple,banana,cherry";
char *token;
// 첫 번째 토큰
token = strtok(str, ",");
while (token != NULL) {
printf("%s\n", token);
token = strtok(NULL, ","); // 다음 토큰
}
// 출력:
// apple
// banana
// cherry
// 여러 구분자 사용
char str2[] = "apple;banana,cherry:grape";
token = strtok(str2, ";,:"); // 세미콜론, 쉼표, 콜론 모두 구분자
while (token != NULL) {
printf("%s\n", token);
token = strtok(NULL, ";,:");
}
return 0;
}
strspn - 일치하는 문자 개수
#include <string.h>
size_t strspn(const char *s, const char *accept);
s의 시작 부분에서accept에 포함된 문자만 연속으로 나타나는 개수 반환
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "12345abc";
char digits[] = "0123456789";
size_t len = strspn(str, digits);
printf("%zu\n", len); // 5 (처음 5개가 숫자)
return 0;
}
strcspn - 일치하지 않는 문자 개수
#include <string.h>
size_t strcspn(const char *s, const char *reject);
s의 시작 부분에서reject에 포함되지 않은 문자만 연속으로 나타나는 개수 반환
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "hello123";
char digits[] = "0123456789";
size_t len = strcspn(str, digits);
printf("%zu\n", len); // 5 (처음 5개가 숫자가 아님)
return 0;
}
안전한 함수 (C11)
strcpy_s, strcat_s 등
C11 표준에서는 더 안전한 함수들이 추가되었습니다 (일부 컴파일러에서만 지원).
// 예시 (Microsoft Visual C++ 등)
errno_t strcpy_s(char *dest, size_t destsz, const char *src);
errno_t strcat_s(char *dest, size_t destsz, const char *src);
주의사항
- 버퍼 오버플로우:
strcpy,strcat등은 버퍼 크기를 확인하지 않음 - NULL 포인터: 모든 함수는 유효한 포인터를 받아야 함
- 메모리 겹침:
memcpy는 메모리가 겹치면 안 됨 (겹치면memmove사용) - NULL 문자: 문자열 함수는 NULL 문자(
\0)를 기준으로 동작 - strtok의 재진입 불가:
strtok는 내부 정적 변수를 사용하므로 스레드 안전하지 않음
실전 예제
문자열 뒤집기
#include <stdio.h>
#include <string.h>
void reverse_string(char *str) {
int len = strlen(str);
for (int i = 0; i < len / 2; i++) {
char temp = str[i];
str[i] = str[len - 1 - i];
str[len - 1 - i] = temp;
}
}
int main() {
char str[] = "Hello";
reverse_string(str);
printf("%s\n", str); // "olleH"
return 0;
}
문자열에서 숫자 추출
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void extract_numbers(const char *str) {
while (*str) {
if (isdigit(*str)) {
printf("%c", *str);
}
str++;
}
printf("\n");
}
int main() {
extract_numbers("abc123def456"); // "123456"
return 0;
}
메모리 안전한 문자열 복사
#include <stdio.h>
#include <string.h>
void safe_strcpy(char *dest, size_t dest_size, const char *src) {
if (dest == NULL || src == NULL || dest_size == 0) {
return;
}
size_t src_len = strlen(src);
size_t copy_len = (src_len < dest_size - 1) ? src_len : dest_size - 1;
memcpy(dest, src, copy_len);
dest[copy_len] = '\0';
}
int main() {
char dest[10];
safe_strcpy(dest, sizeof(dest), "Hello, World!");
printf("%s\n", dest); // "Hello, Wo" (안전하게 잘림)
return 0;
}