Skip to content

Latest commit

 

History

History
342 lines (271 loc) · 8.77 KB

211026.md

File metadata and controls

342 lines (271 loc) · 8.77 KB

Day 25

Review C

문자열 복사하기

strcpy 함수 사용, 문자열을 다른 곳으로 복사, string.h에 선언
strcpy(대상문자열, 원본문자열);

  • 대상문자열의 포인터를 반환
char s1[10] = "Hi";
char s2[10];

strcpy(s2, s1); // s1의 문자열을 s2로 복사

printf("%s", s2); // Hi 출력

포인터 문자열 복사

char *s1 = "Hi";
char *s2 = malloc(sizeof(char) * 10);

strcpy(s2, s1);

printf("%s", s2); // Hi 출력

free(s2);

만약 char *s2 = ""로 선언하고 초기화하면 에러가 발생한다. 이유는 s2에 저장된 메모리 주소는 복사할 공간도 없고, 읽기 전용이기 때문.

문자열 붙이기

strcat 함수 사용, 문자열을 서로 붙임, string.h에 선언
strcat(최종문자열, 붙일문자열);

  • 최종 문자열의 포인터를 반환
char s1 = [10] = "day";
char s2 = [15] = "To";

strcat(s2, s1); // s2 뒤에 s1을 붙임

printf("%s", s2); // Today 출력

포인터에서 붙이기

char *s1 = "day";
char *s2 = malloc(sizeof(char) * 20);

strcpy(s2, "To"); // s2에 Hello 문자열 복사

strcat(s2, s1); // s2 뒤에 s1을 붙임

printf("%s", s2); // Today 출력

free(s2);

이번에도 그냥 char *s2 = "To"로 선언하고 strcat을 쓰면 에러가 발생한다. 읽기 전용 메모리이기 때문

배열 -> 포인터로 문자열 복사

char s1[10] = "Hi";
char *s2 = malloc(sizeof(char) * 10);

strcpy(s2, s1);

printf("%s", s2); // Hi 출력

free(s2);

배열 -> 포인터로 문자열 붙이기

char s1[10] = "day";
char *s2 = malloc(sizeof(char) * 20);

strcpy(s2, "To");

strcat(s2, s1);

printf("%s", s2); // Today 출력

free(s2);

배열 형태로 문자열 만들기

sprintf 함수 사용, 서식을 지정하여 문자열을 만들 수 있음, stdio.h에 선언
sprintf(배열, 서식, 값);
sprintf(배열, 서식, 값1, 값2, ...);

  • 성공하면 만든 문자열의 길이를 반환, 실패하면 음수 반환
char s1[20];
char s2[30];

sprintf(s1, "Hello, %s", "world");

printf("%s", s1); // Hello, world 출력

sprintf(s2, "%c %d %f %e", 'a', 10, 3.2f, 1.123456e-21f); // 문자, 정수, 실수를 문자열로 만들기

printf("%s", s1); // a 10 3.200000 1.123456e-21 출력

포인터에 문자열 만들기

sprintf 함수 사용

char *s1 = malloc(sizeof(char) *20);

sprintf(s1, "Hello, %s", "world");

printf("%s", s1); // Hello, world 출력

free(s1);

문자열에서 문자로 검색

strchr 함수 사용, string.h에 선언
strchr(대상문자열, 검색할문자);

  • 문자를 찾았으면 문자로 시작하는 문자열의 포인터를 반환, 문자가 없으면 NULL을 반환
char s1[30] = "Today I Learned";
char *ptr = strchr(s1, 'a'); // 'a'로 시작하는 문자열 검색, 포인터 반환

while(ptr != NULL) // 검색된 문자열이 없을 때까지 반복
{
    printf("%s\n", ptr); // 검색된 문자열 출력
    ptr = strchr(ptr + 1, 'a'); // 포인터에 1을 더하여 a 다음부터 검색
}

/*
출력 결과물
ay I Learned
arned
*/

문자열에서 오른쪽 끝부터 문자로 검색

strrchr 함수 사용, string.h에 선언
strrchr(대상문자열, 검색할문자);

  • 문자열의 끝에서부터 역순으로 검색해서 문자를 찾았으면 해당 문자로 시작하는 문자열의 포인터를 반환, 문자가 없으면 NULL 반환
char s1[30] = "Today I Learned";

char *ptr = strrchr(s1, 'a'); // 문자열 끝에서부터 'a'로 시작하는 문자열 검색, 포인터 반환

printf("%s", ptr); // arned 출력

문자열 안에서 문자열로 검색

strstr 함수 사용, string.h에 선언
strstr(대상문자열, 검색할문자열);

  • 문자열을 찾았으면 문자열로 시작하는 문자열의 포인터를 반환, 문자열이 없으면 NULL 반환
char s1[30] = "Today I Learned";

char *ptr = strstr(s1, "rn"); // rn으로 시작하는 문자열 검색, 포인터 반환

printf("%s", ptr); // rned 출력

while문을 이용해서 strstr(ptr + 1, "rn")으로 계속 찾을 수도 있음

문자를 기준으로 문자열 자르기

strtok 함수 사용, string.h에 선언
strtok(대상문자열, 기준문자);

  • 자른 문자열을 반환, 더 이상 자를 문자열이 없으면 NULL 반환
char s1[30] = "Monitor with Keyboard";

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

while(ptr != NULL)
{
    printf("%s\n", ptr); // 자른 문자열 출력
    ptr = strtok(NULL, " "); // 다음 문자열을 잘라서 포인터 반환
}
/*
출력 결과물
Monitor
with
Keyboard
*/

strtok(NULL, " ")는 Monitor을 자르고 " "를 NULL로 채운다. 그래서 NULL을 넣어주어 다음으로 넘어 갈 수 있음.
포인터에서는 동적 메모리 할당을 한 후에 문자열을 복사해줘야 strtok을 사용할 수 있다.
선언과 동시에 초기화하여 문자열 리터럴의 주소가 포인터에 들어가면 읽기 전용이 되어 strtok을 사용할 수 없는 것이다.

char *s1 = malloc(sizeof(char) * 30);

strcpy(s1, "Monitor with Mouse");

char *ptr = strtok(s1, " ");

while (ptr != NULL)
{
   printf("%s\n", ptr);
   ptr = strtok(NULL, " ");
}

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

자른 문자열 보관

char s1[30] = "Monitor with Mouse";
char *sArr[10] = {NULL, }; // 크기가 10인 문자열 포인터 배열을 선언하고 NULL로 초기화
int i = 0;

char *ptr = strtok(s1, " ");

while(ptr != NULL)
{
    sArr[i] = ptr; // 문자열을 자른 뒤 메모리 주소를 문자열 포인터 배열에 저장
    i++; // 인덱스 증가

    ptr = strtok(NULL, " "); // 다음 문자열 잘라서 포인터 반환
}

for (int i = 0; i < 10; i++)
{
    if (sArr[i] != NULL)
        printf("%s\n", sArr[i]);
}

문자열을 정수로 변환

atoi 함수 사용, 10진법으로 표기된 문자열을 정수로 바꿀 수 있음, stdlib.h에 선언
문자열은 정수로 되어있어야 하고, 영문자나 특수문자가 포함되면 해당 문자부터는 변환하지 않음, 처음부터 숫자가 아니면 0을 반환해 버림
atoi(문자열);

  • 성공하면 변환된 정수를 반환, 실패하면 0 반환
char *s1 = "283";
int num1;

num1 = atoi(s1);

printf("%d", num1); // 283 출력
/*
283a -> 283
283a30 -> 283
a30 -> 0
!30 -> 0
*/

특정 진법으로 표기된 문자열을 정수로 변환

strtol 함수 사용, stdlib.h에 선언
strtol(문자열, 끝포인터, 진법);

  • 성공하면 변환된 정수를 반환, 실패하면 0 반환
char *s1 = "0xaf10";
int num1;

num1 = strtol(s1, NULL, 16); // 16진법으로 표기된 문자열을 정수로 변환

printf("%x %d", num1, num1); // af10 44816 출력

여러개의 정수로 된 문자열 변환

char *s1 = "0xaf10 42 0x27c 9952";
int num1, num2, num3, num4;
char *end; // 이전 숫자의 끝 부분을 저장하기 위한 포인터

num1 = strtol(s1, &end, 16);
num2 = strtol(end, &end, 10);
num3 = strtol(end, &end, 16);
num4 = strtol(end, NULL, 10);

printf("%x %d %X %d", num1, num2, num3, num4); // af10 42 27C 9952 출력

문자열을 실수로 변환

atof 함수 사용, stdlib.h에 선언
atof도 영문자나 특수문자에 대해서 atoi와 같은 대처를 한다.
atof(문자열);

  • 성공하면 변환된 실수를 반호나, 실패하면 0 반환
char *s1 = "12.345678";
float num1;

num1 = atof(s1);

printf("%f", num1); // 12.345678 출력

지수 표기법으로 된 문자열도 실수로 변경 가능

여러개의 실수로 된 문자열을 실수로 변환도 가능
strtof 함수를 사용, stdlib.h에 선언
strtof(문자열, 끝포인터);

  • 성공하면 변환된 실수를 반환, 실패하면 0 반환
num1 = strtof(s1, &end);
num2 = strtof(end, &end);
num3 = strtof(end, NULL);

수를 문자열로 변환

sprintf 함수 사용, stdio.h에 선언
sprintf(문자열, "%d", 정수);

  • %d외에도 %x, %X도 가능
  • 실수는 %f를 사용하면 됨

회문판별

char word[30]; // 단어를 저장할 배열
int length; // 문자열의 길이
bool isPalindrome = true; // 회문 판별값을 저장할 변수, 초깃값은 true

printf("단어를 입력 : ");
scanf("%s", word);

length = strlen(word); // 문자열 길이 구하기

// 0부터 문자열 길이의 절반만큼 반복
for (int i = 0; i < length / 2; i++)
{
    // 왼쪽 문자와 오른쪽 문자를 비교하여 문자가 다른지 판별
    if (word[i] != word[length - 1 - i])
    {
        // 회문이 아닌 경우
        isPalindrome = false;
        break;
    }
}

printf("%d", isPalindrome); // 회문 판별값 출력

3-gram

char s1[30] = "Serious?";
int length;

length = strlen(s1);

for (int i = 0; i < length - 2; i++)
{
    printf("%c%c%c", s1[i], s1[i + 1], s1[i + 2]);
}
/*
출력 결과물
Ser
eri
rio
iou
ous
us?
*/