Skip to main content

Command Palette

Search for a command to run...

[배열] 문자열의 활용

Updated
•3 min read•View as Markdown
[배열] 문자열의 활용
W

안녕하세요! 프론트엔드 개발자 woodstock입니다.

저는 매일 조금씩 발전하고자 하는 마음으로 개발공부를 시작했고, 이 블로그는 그 과정에서 배우고 성장하는 이야기를 담고 있습니다.

여러분의 피드백과 조언은 언제나 환영합니다! 함께 배우고 성장하는 과정을 즐길 수 있기를 기대합니다.

문자열 안에 포함되어 있는 문자를 검색하기 위해서는 어떻게 해야 할까?

그리고 특정 문자를 다른 문자로 바꾸기 위해서는 어떻게 해야 할까?

문자열의 길이 및 탐색

사용자로 부터 문자열을 입력받아 한 글자씩 출력하는 프로그램을 만들어 보자.

간단하게 for 루프를 통해 문자열의 인덱스를 하나씩 증가시켜가면서 해당하는 문자를 출력하면 될텐데, 그럼 문자열의 끝은 어떻게 알 수 있을까?

한가지 방법은 해당하는 인덱스의 문자가 널 종단 문자, 즉 \0와 일치하는지 검사하는 것이다.

즉, s라는 문자열이 있다고 할 때 for (int i = 0; s[i] != ‘\0’; i++) { ..}과 같은 루프를 사용하면 될 것 같다.

하지만 아래 코드와 같이 strlen() 이라는 함수를 사용할 수도 있다.

#include <cs50.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
    string s = get_string("Input: ");
    printf("Output:\n");
    for (int i = 0, n = strlen(s); i < n; i++)
    {
        printf("%c\n", s[i]);
    }
}

strlen은 문자열의 길이를 알려주는 함수로, string.h 라이브러리 안에 포함되어 있다.

위 코드에서는 n이라는 변수에 문자열 s의 길이를 저장하고, 해당 길이 만큼만 for 루프를 순환한다.

따라서 일일이 널 종단 문자를 검사하는 것 보다 훨씬 효율적이다.

문자열 탐색 및 수정

사용자로부터 문자열을 입력받아 대문자로 바꿔주는 프로그램을 아래와 같이 작성할 수 있다.

#include <cs50.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
    string s = get_string("Before: ");
    printf("After:  ");
    for (int i = 0, n = strlen(s); i < n; i++)
    {
        if (s[i] >= 'a' && s[i] <= 'z')
        {
            printf("%c", s[i] - 32);
        }
        else
        {
            printf("%c", s[i]);
        }
    }
    printf("\n");
}

먼저 사용자로부터 입력받은 문자를 s라는 변수에 저장한다.

그리고 s의 길이만큼 for 루프를 돌면서, 각 인덱스에 해당하는 문자가 ‘a’보다 크고 ‘z’보다 작은지 검사한다.

즉, 소문자인지 검사하는 것과 동일하다.

여기서 문자의 대소비교가 가능한 이유는 ASCII값, 즉 그 문자가 정의되는 ASCII 코드 상에서의 숫자값으로 비교할 수 있기 때문이다.

또한 알파벳의 ASCII 값을 잘 살펴보면 각 알파벳의 소문자와 대문자는 32씩 차이가 남을 확인할 수 있다.

따라서 각 문자가 소문자인 경우 그 값에서 32를 뺀 후에 ‘문자’ 형태로 출력하면 대문자가 출력이 된다.

각 문자가 이미 대문자인 경우는 그냥 그대로 출력하면 된다.

이와 동일한 작업을 수행하는 함수가 ctype 라이브러리에 toupper() 이라는 함수로 정의되어 있다.

이를 이용하면 간단하게 아래와 같이 대문자 변환 프로그램을 작성할 수 있다.

#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
    string s = get_string("Before: ");
    printf("After:  ");
    for (int i = 0, n = strlen(s); i < n; i++)
    {
        printf("%c", toupper(s[i]));
    }
    printf("\n");
}


생각해보기

string.h와 ctype.h의 라이브러리에 다른 어떤 함수가 있는지 확인해 보고, 어떤 함수를 어떻게 활용해 볼 수 있을지 생각해보자.

정답

  1. string.h 라이브러리는 C 언어에서 문자열을 다루는 데 사용되는 다양한 함수들을 제공한다.
  2. strlen(): 문자열의 길이를 계산한다.
  3. strcpy(): 한 문자열을 다른 문자열로 복사한다.
  4. strcat(): 두 문자열을 연결한다.
  5. strcmp(): 두 문자열을 비교한다.
  6. strlwr(): 문자열을 소문자로 변환한다.
  7. strupr(): 문자열을 대문자로 변환한다.
  8. gets()와 puts(): 문자열 입력을 받고 출력하는 함수이지만, 이들은 stdio.h 헤더 파일에 정의되어 있다.

  9. ctype.h 라이브러리는 문자 데이터를 처리하는 데 사용되는 함수들을 제공한다.

  10. isalpha(): 문자가 알파벳인지 확인한다.
  11. isdigit(): 문자가 숫자인지 확인한다.
  12. isalnum(): 문자가 알파벳 또는 숫자인지 확인한다.
  13. isupper(): 문자가 대문자인지 확인한다.
  14. islower(): 문자가 소문자인지 확인한다.
  15. toupper(): 문자를 대문자로 변환한다.
  16. tolower(): 문자를 소문자로 변환한다.

More from this blog

💥 new Array(length).map()으로 배열 초기화 시 콜백이 실행되지 않는 문제

JavaScript에서 배열을 초기화하려고 new Array(4).map(() => [])을 사용했는데 의도대로 동작하지 않았다. 원인을 찾아보니 JavaScript의 빈 슬롯과 undefined의 차이, 그리고 map() 메서드가 빈 슬롯에 대해 콜백을 실행하지 않는다는 특성때문이었다. 문제 상황 특정 크기의 배열을 만들고 각 요소를 []로 초기화 하려고 했다. const result = new Array(4).map(() => []); co...

Jun 28, 20252 min read17

💥 에러 메시지와 스택 트레이스 분석을 통해 문제 해결하기

JavaScript로 카드 게임 로직을 구현하던 중 TypeError: Cannot read properties of undefined라는 에러를 만났다. 코드가 복잡하고 짐작가는 부분이 단번에 떠오르지 않아 막막했는데, 에러 메세지와 스택 트레이스를 차근차근 분석해가며 원인을 찾아낸 과정을 기록해본다. 에러 발생 게임 로직을 테스트하던 중 특정 입력에서 다음과 같은 에러가 발생했다. TypeError: Cannot read properties...

Jun 25, 20254 min read11

🧐 적절한 함수명과 단일 책임으로 코드 개선하기

이 글에서는 JavaScript로 구현된 보드게임의 로직을 개선하는 과정을 다루며, 개선 과정은 함수명 개선 → 중복 제거 → 책임 분리의 단계로 이루어져있다. 작동하지만 개선이 필요한 코드 처음에 작성한 코드는 기능적으로는 문제없이 동작했지만, 더 나은 방식을 고민하다 보니 여러 개선점을 찾을 수 있었다. function checkLadder(position) { switch (position) { case 4: return 14;...

Jun 23, 20253 min read23

작심삼십일 - TypeScript 강의를 완강하다.

유데미 작심삼십일 챌린지에 참여하다 작심삼십일 챌린지는 유데미의 한국 런칭 3주년을 기념한 이벤트 중 하나로, 30일 동안 유데미 강의를 들으며 인증을 하는 챌린지이다.취업 준비를 하면서 여러가지 요인으로(주로 심리적이지만..) 학습 루틴이 망가졌던 찰나에 이 이벤트를 보게되었고, 마침 기존에 사두고 볼 엄두가 안 났던 타입스크립트 강의가 있었기에 옳다구나! 하고 신청했었다. 챌린지를 통해 무엇을 배웠나? 챌린지의 목표로 정한 강의는 유데미에...

Nov 18, 20242 min read58
작심삼십일 - TypeScript 강의를 완강하다.

woodstock's devlog

215 posts

안녕하세요! 프론트엔드 개발자 woodstock입니다.

제 블로그에서는 프론트엔드 개발에 대한 다양한 주제를 다룹니다.

JavaScript, TypeScript, React, Next.js 등의 기술을 활용하여 실제 프로젝트를 진행하면서 얻은 경험과 지식을 공유하고자 하며, 컴퓨터 과학(CS)의 기본 개념과 알고리즘, 자료구조 등에 대해서도 다룹니다.