TCHAR를 쓰면 tcs~() 함수들을 프로젝트속성에 따라 컴파일러가 멀티바이트와 유니코드 알아서 바꿔준다.
어떤함수들이 있는지, 사용법과 함께 정리해보자.
1. Formatted I/O
MACRO |
ANSI |
UNICODE |
설명/예제 |
_tprintf |
printf |
wprintf |
콘솔창에서 출력하기위해 쓴다. _tprintf( _T("format %s %d"), (TCHAR*)szTemp, (int)nIdx); |
_ftprintf |
fprintf |
fwprintf |
파일에 출력하는 용도. 파일 핸들이 필요하다. _ftprintf( (FILE*) _tfopen(_T("filename"), _T("w")), _T("format %s"), szTemp); |
_stprintf |
sprint |
swprintf |
버퍼에 포맷을 넣는용도 TCHAR szDec[128] = {0,}; _stprintf(szDec, _T("format %s"), szTemp); |
_sntprintf |
_snprintf |
_snwprintf |
위에꺼(sprintf)랑 용도는 같지만 버퍼사이즈가 들어간다. _sntprintf(szDec, 128, _T("format %s"), szTemp); |
_vtprintf |
vprintf |
vwprintf |
가변인자 리스트를 사용하는 printf va_list lpStart; |
_vftprintf |
vfprintf |
vfwprintf |
가변인자 리스트를 사용하는 fprintf |
_vstprintf |
vsprintf |
vswprintf |
가변인자 리스트를 사용하는 sprintf |
_vsntprintf |
_vsnprintf |
_vsnwprintf |
가변인자 리스트를 사용하는 snprintf |
_tscanf |
scanf |
wscanf |
값 입력함수 int num; TCHAR szText[128] = {0,};
_tscanf(_T("%d"), &num); _tscanf(_T("%s"), szText); |
_ftscanf |
fscanf |
fwscanf |
파일에서 읽어온다. FILE* fp = _tfopen(_T("filename"), _T("w")); int num; TCHAR szText[128] = {0,}; _ftscanf(fp, _T("%d"), &num); _ftscanf(fp, _T("%s"), szText); |
_stscanf |
sscanf |
swscanf |
문자열을 다른타입으로 바꿀때 주로 사용된다. TCHAR szNum[] = _T("1234"); int num; _stscanf(szNum, _T("%d"), &num); |
추가로 컴파일러에서 해당 함수들을 에러나 경고가 나타나는 경우가 있다.
대체로 printf 같은걸 printf_s로 쓰라는 메시지인듯하다.
이유는 내부적으로 버퍼 오버플로우가 발생할수 있기 때문이다.
대부분은 _s가 붙은 함수들이 이를 대체하고 있다.
해당함수(_s) 들은 대부분 버퍼사이즈만 추가하여 사용가능하기 때문에 따로 기재하지는 않겠다.
그리고 이 함수들을 그냥 쓰려면 전처리기에 _CRT_SECURE_NO_WARNINGS 를 추가하거나
#define로 선언해두면 에러나 경고는 사라지기는 한다. (안정성은 보장못함...)
2. Formatted I/O
MACRO |
ANSI |
UNICODE |
설명 |
_fgettc |
fgetc |
fgetwc |
파일에서 문자 하나 읽어온다. int fgetc(FILE* stream); |
_fputtc |
fputc |
fputwc |
파일에 문자 하나 기록한다. int fputc(int character, FILE* stream); |
_fgetts |
fgets |
fgetwc |
파일에서 문자열을 읽어온다. char* fgets(char* str, int num, FILE* stream); num -1 만큼 문자열을 읽어온다. (마지막은 자동으로 NULL로 채워진다. 그래서 -1) 또는 EOF (end of file) 까지
FILE* fp = _tfopen(_T("filename"), _T("r")); TCHAR szBuf[256] = {0,}; { _tprintf("%s", szBuf); } fclose(fp); // fclose는 문자열입력이 없기때문에 유니코드가 따로없다. |
_fputts |
fputs |
fputws |
파일에 문자열을 기록한다. int fputs(const char* str, FILE* stream); FILE* fp = _tfopen(_T("filename"), _T("a")); |
_gettc |
getc |
getwc |
문자하나를 파일, 콘솔(stdin)입력받는다. int getc(FILE* stream); |
_puttc |
putc |
putwc |
문자하나를 파일, 콘솔(stdout)에 출력 int putc(int character, FILE* stream); |
_gettchar |
getchar |
getwchar |
문자하나를 콘솔로 입력받는다. int getchar(void); |
_puttchar |
putchar |
putwchar |
문자하나를 콘솔로 출력한다. int putchar(int character); |
_getts |
gets |
_getws |
문자열을 콘솔로 입력받는다. char* gets(char* buffer); |
_putts |
puts |
_putws |
문자열을 콘솔로 출력한다. int puts( const char *str ); |
_ungettc |
ungetc |
ungetwc |
스트림에 문자를 다시 집어 넣는다(unget) int ungetc(int character, FILE* stream); |
|
fwrite |
|
파일 쓰기 size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
FILE *fp = _tfopen(_T("filename.txt"), _T("w"));
// UniCode BOM 기록 |
|
fread |
|
파일 읽기 size_t fread( void *buffer, size_t size, size_t count, FILE *stream );
FILE *fp = _tfopen(_T("filename.txt"), _T("r"));
// UniCode BOM 검사 if( 0xFEFF != wMark ) { fclose(fp); reutrn; }
WCHAR szBuf[256] = {0,}; while(fread(szBuf, sizeof(WCHAR), 256-1, fp)) // 버퍼의 마지막포인터 NULL 유지 { _putts(szBuf); } |
추가로 파일 입출력관련해서 더 적었습니다.
비슷하지만 미묘한 차이 getch(), getchar()
getchar(), getch(), getche()의 차이점. 예제소스 & 그림
알듯 모를듯 한 미묘한 3가지 함수의 차이점에 대해서 파헤쳐 보자 -_-!! getchar(), getch(), getche()의 차이점 !! 비슷해 보이는 3가지 종류의 함수가 있다. 차이가 뭘까? 어떻게 보면 사실 결과는 같을 수도..
kcoder.tistory.com
3. 파일 오픈 함수
MACRO |
ANSI |
UNICODE |
설명 |
_tfopen |
fopen |
_wfopen |
파일 열기 FILE* fp = _tfopen(_T("filename.txt"), _T("r")); |
_tfreopen |
freopen |
_wfreopen |
파일 닫고 다시 열기(옵션전환용?) FILE* fp = _tfopen(_T("filename.txt"), _T("r"), fp); |
fopen 옵션 참고
r = 읽기/ w = 쓰기 / a = 추가
rb = 바이너리읽기/ rw = 바이너리쓰기/ ra = 바이너리추가
뒤에 b(바이너리)가 없을시 기본 t(텍스트)로 열게된다.
r+, w+, a+는 추가적으로 읽기쓰기가 모두 가능하다.
4. 문자열 변환 함수
MACRO |
ANSI |
UNICODE |
설명 |
_tcstod |
strtod |
wcstod |
버퍼에서 실수(double)를 추출한다 (string to Double) TCHAR szText[] = _T("123.112asdasd"); TCHAR* pPos = nullptr; double value = _tcstod(src, pPos); // 123.112 // pPos = szText[7] |
_tcstol |
strtol |
wcstol |
버퍼에서 정수를 추출 (+진법) (string to long) TCHAR szText[] = _T("123.112asdasd"); int num1 = _tcstol(szText, nullptr, 10); // 123 |
_tcstoul |
strtoul |
wcstoul |
버퍼에서 unsigned 정수를 추출 (string to unsigned long) 잘 사용하면 atoi 류 보다 나을수 있다. |
_itot |
_itoa |
_itow |
TCHAR _itot(int val, TCHAR* buf, int radix); // 정수를 문자열로 |
_ltot |
_ltoa |
_ltow |
TCHAR ltot (long val, TCHAR* buf, int radix); |
_ultot |
_ultoa |
_ultow |
TCHAR _ultot (unsigned long val, TCHAR* buf, int radix); |
_ttoi |
atoi |
_wtoi |
int _ttoi (const TCHAR* str); // 문자열을 정수로 |
_ttoll |
atoll |
_wtoll |
long long _ttoll (const TCHAR* str); // 문자열을 64정수로 |
5. String function
MACRO |
ANSI |
UNICODE |
설명 |
_tcscat |
strcat |
wcscat |
문자열 연결용 char *strcat(char *_Destination, char const *_Source); TCHAR szSrc[10] = _T("world");
_tcscat(szDec, szSrc); // szDec 뒤에 szSrc를 붙임 // szDec = Hello world |
_tcschr |
strchr |
wcschr |
문자 검색용 char *strchr(char * const _String, int const _Ch); TCHAR szTest = _T("Test abcd Text"); TCHAR* ptr = _tcschr(s1, 'a'); // 'a'로 시작하는 문자열 검색, 포인터 반환 // ptr == szTest[5] |
_tcsrchr |
strrchr |
wcsrchr |
strchr의 리버스 버전, 뒤에서부터 검색한다. |
_tcscspn |
strcspn |
wcscspn |
strchr 의 배열버전, str1에 str2의 문자가 하나라도 포함되어 있는가? |
_tcsspn |
strspn |
wcsspn |
strcspn의 반대, 포함되지 않은 첫번째 배열인덱스를 출력 |
_tcspbrk |
strpbrk |
wcspbrk |
strcspn의 포인터 버전, 포인터를 리턴한다. |
_tcscmp |
strcmp |
wcscmp |
문자열 비교용 int strcmp(const *_Str1, char const *_Str2); 리턴값 -1: ASCII 코드 기준으로 문자열2(s2)가 클 때
TCHAR szTest[] = _T("Hello World!!"); int nRet = _tcscmp(_T("End Game"), szTest); |
_tcsicmp |
_stricmp |
_wcsicmp |
대소문자 구분없는 strcmp |
_tcsncicmp _tcsnicmp |
_strnicmp |
_wcsnicmp |
strncmp에 추가로 비교할 문자열 길이를 제한할수있다. |
_tcscpy |
strcpy |
wcscpy |
char *strcpy(char *_Dest, char const *_Source); // 문자열 복사 return _Dest |
_tcslen |
strlen |
wcslen |
size_t strlen(const *_Str); // 문자열 길이반환 (널문자제외) |
_tcsstr |
strstr |
wcsstr |
문자열 안에서 문자열 검색, 포인터 리턴 char *strstr(char * const _String, char const * const _SubString);
TCHAR szText[] = _T("Hello world!!"); TCHAR* pRet = _tcsstr(szText, _T("wor")); // wor으로 시작하는 문자열 검색 // pRet == szText[6] |
_tcstok |
strtok |
wcstok |
문자열 자르기 (원본 변형에 주의) char *strtok(char *_String, char const *_Delimiter); TCHAR szText = _T("Apple, Melon, Grape"); TCHAR* pRet = _tcstok(szText, _T(", ")); // ", " 문자열을 널문자로 치환하고 문자열 포인터 리턴 // szText[5] = ',' -> '\0' 변경됨
while (pRet) // (주의) 내부변수 때문에 스레드 환경에서 문제 발생가능성 있음
[출력 예] Apple Melon Grape |
_tcsdup |
_strdup |
_wcsdup |
문자열 복제, 메모리 할당(malloc) TCHAR szBuf[256] = { 0, }; |
_tcsset |
_strset |
_wcsset |
문자열을 특정문자로 바꾸는 함수 char *_strset( char *string, int c ); TCHAR szTest = _T("Hello world!!\n"); _tcsset(szTest, '%'); // Hello world!!\n -> %%%%%%%%%%%%%% |
_tcsnset _tcsncset |
_strnset |
_wcsnset |
문자열을 특정문자로 바꾸는 함수 (+바꿀개수) char *_strnset( char *string, int c , size_t count );
TCHAR szTest = _T("Hello world!!\n"); _tcsnset(szTest, '%', 3); // Hello world!!\n -> %%%lo world!!\n |
_tcsrev |
_strrev |
_wcsrev |
문자열 뒤집기 char *_strrev( char *string ); TCHAR szTest = _T("Hello world!!\n"); _tcsrev(szTest); // Hello world!!\n -> \n!!dlrow olleH |
_tcslwr |
_strlwr |
_wcslwr |
소문자로 변경 char *_strlwr( char *string ); TCHAR szTest = _T("Hello world!!\n"); _tcslwr(szTest); // Hello world!!\n -> hello world!!\n |
_tcsupr |
_strupr |
_wcsupr |
대문자로 변경 char *_strupr( char *string ); TCHAR szTest = _T("Hello world!!\n"); _strupr(szTest); // Hello world!!\n -> HELLO WORLD!!\n |
'C++' 카테고리의 다른 글
C++11 람다 함수 (Lambda Function) (0) | 2020.04.26 |
---|---|
C++11 stl에 추가된 emplace(insert), emplace_back(push_back) (0) | 2020.04.17 |
C++11 가변인자 템플릿 (Variadic template) (0) | 2020.04.12 |
C++11 enum class (1) | 2020.04.12 |
printf문의 서식지정자 (0) | 2020.04.12 |