문자비교를 통한 문자열 split 하기
절름발이 프로그래머/C언어, C++ 과 Visual C++ / 2009. 3. 6. 16:21
str() 계열의 함수나 다른 문자열 클래스를 이용하지 않는,
순수한 문자버퍼의 문자열 split 하는 예제
속도도 빠르고, 알고리즘도 신뢰할 수 있다.
순수 C언어 방신의 Split 방식이다.
----------------------------------------------------------------------------------
DWORD len = 0, count = 0, line_count = 0 ; // 토큰 길이 변수, 토큰 개수 변수, 전체 행 개수 변수
char line[LINE_MAX_STRING_LEN] = {0}; // 한 라인 문자열
char *pLine, *cur_ptr, *start_pos; // 라인 문자열 포인터, 라인내의 현재위치 포인터, 라인내의 시작위치 포인터
char ipAddr[20] = {0}; // IP 주소를 담기 위한 문자열
char url[LINE_MAX_STRING_LEN] = {0}; // URL을 담기 위한 문자열
// 입력 파일 스트림으로 파일 열기
ifstream logfile("a.txt");
while( logFile.getline( line, LINE_MAX_STRING_LEN, '\n') ) // 각 라인을 읽어서, line 문자열 배열에 저장
{
// do something
count = 1; // 토큰 개수 지정, 초기화
line_count++; // 전체 행 저장 변수 증가
if( logFile.fail() == 1 ) // 라인을 읽다가 실패한 경우, 에러 출력 파일내용 삭제
{
cout << "Line is too Long.. Just Process " << LINE_MAX_STRING_LEN << "bytes.. (" << line_count << ")" << endl;
logFile.clear();
}
if( line_count % 1000000 == 0 ) // 전체 라인 행수가 100만을 넘을 때마다, 화면에 표시를 해준다.
cout << " Now Processing " << line_count << "th line" << endl;
if( line[0] == '#' ) continue; // 라인의 첫 시작문자가 # 이면, 건너뛴다.
pLine = line; // 라인 문자열 포인터를 지정한다. 초기화
cur_ptr = pLine; // 라인 문자열 처음에 현재 위치 포인터를 지정한다. 초기화
// 라인을 분석하기 시작한다.
while( *cur_ptr != '\0' && *cur_ptr != '\r' && *cur_ptr != '\n' ) // NULL문자, Carrage-Return문자, New Line 문자가 나올 때까지 루프를 유지한다.
{
len = 1; // 라인 문자열에서 추출되는 토큰 길이를 1로 지정, 초기화
// 공백문자는 뛰어넘음
while( *cur_ptr == ' ' || *cur_ptr == '\t' )
{
if( *cur_ptr == '\0' ) break; // 중간에 NULL 문자가 나오면 루프 종료
cur_ptr++;
}
if( *cur_ptr == '\0' ) // 중간에 NULL 문자가 나오면 루프 종료
break;
start_pos = cur_ptr; // 토큰 시작위치를 현재로 설정, 초기화
// 공백문자가 아닌, 실제 문자에 대해서 문자 개수를 센다.
while( *cur_ptr != ' ' && *cur_ptr != '\t' && *cur_ptr != '\0' ) { cur_ptr++; len++; }
// 원하는 토큰을 저장한다.
if( count == gSrcIPIdx )
{
len = min( len, 18 );
lstrcpyn( ipAddr, start_pos, len );
ipAddr[len] = '\0';
} else if ( count == gUrlIdx )
{
len = min( len, LINE_MAX_STRING_LEN - 2);
lstrcpyn( url, start_pos, len );
url[len] = '\0';
}
count++; // 토큰 개수 증가
}
}