파일 이름 처리나 데이터 정제 작업을 하다 보면 문자열에서 :, ?, \, /, <, >, |, *처럼 시스템에서 허용되지 않는 특수 문자를 걸러내야 하는 경우가 많습니다. 이번 글에서는 C++로 이러한 금지된 문자를 제거하는 함수를 직접 구현하는 방법을 알아보겠습니다.
문제 이해하기
입력: str = "Hello: Welco*me/ to Tu>torials point|." 출력: "Hello Welcome to Tutorials point." 설명: 입력 문자열에 포함된 금지 문자들이 모두 제거되어, 결과 문자열에는 더 이상 금지 문자가 남아 있지 않습니다. 입력: str = "How/ are y*ou doi,ng?" 출력: "How are you doing"
문제 해결 접근 방법
이 문제는 다음과 같은 간단한 방법으로 해결할 수 있습니다.
- 문자열을 한쪽 끝부터 차례대로 순회(traverse)합니다.
- 각 문자가 금지된 문자 목록에 포함되어 있는지 하나씩 검사합니다.
- 금지된 문자라면 해당 문자를 제거합니다.
- 금지되지 않은 문자만 새 문자열에 담거나, 널(NULL) 값으로 대체하는 방식으로 처리할 수 있습니다.
C++ 구현 예제
위 접근 방식을 C++ 코드로 구현하면 다음과 같습니다.
#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
// 금지된 문자를 제거하는 함수
void removeforbidden(char* str){
int j = 0;
int n = strlen(str);
// 문자열을 순회하며 금지된 문자를 검사합니다.
for(int i = 0; i < n; i++){
switch(str[i]){
case '/':
case '\\':
case ':':
case '?':
case '"':
case '<':
case '>':
case '|':
case '*':
// 금지된 문자는 복사하지 않고 건너뜁니다.
break;
default:
str[j++] = str[i];
}
}
str[j] = '\0'; // 문자열의 끝을 표시
// 결과 문자열을 출력합니다.
cout << str;
return;
}
int main(){
char str[] = "Hello: Welco*me/ to Tu>torial?s point|.";
removeforbidden(str);
return 0;
}
실행 결과
Hello Welcome to Tutorials point.
코드 설명
- switch 문 활용: 문자열을 순회하면서 각 문자를 case 라벨에 나열된 금지 문자들과 비교합니다. 여러 case가 연달아 나열되어 있으므로, 목록 중 어느 하나라도 일치하면 동일한 분기로 처리됩니다.
- 문자 제거: 문자가 금지 문자와 일치하면 복사하지 않고 건너뛰므로, 결과적으로 해당 문자가 문자열에서 제거된 것과 같은 효과를 냅니다.
- 두 포인터 기법: 읽는 위치(i)와 쓰는 위치(j)를 분리하여, 금지 문자가 아닌 문자만 앞쪽으로 당겨 오는 방식으로 동작합니다. 마지막에 널 문자('\0')를 삽입해 문자열의 끝을 표시합니다.
마무리
이번 튜토리얼에서는 :, ?, \, /, <, >, |, * 같은 금지된 문자를 문자열에서 제거하는 함수를 만드는 방법을 살펴보았습니다. 문자열을 한 번만 순회하며 각 문자를 금지 문자 목록과 비교하는 간단한 접근 방식으로, O(n) 시간 복잡도 안에 문제를 해결할 수 있습니다.
동일한 로직은 C, Java, Python 등 다른 프로그래밍 언어로도 손쉽게 구현할 수 있습니다. 실제 프로젝트에서는 파일명 정규화, URL 클렌징, 사용자 입력 검증 등 다양한 상황에서 이러한 문자 필터링 기법이 유용하게 활용됩니다. 이 튜토리얼이 여러분에게 도움이 되기를 바랍니다.