문자와 문자열
- 입력과 출력
- 스트림
프로그램과 입력 및 출력 장치를 연결해주는 소프트웨어적으로 구현되어 있는 도구, 입출력 장치와 프로그램을 연결해주는 가상의 다리이다. 운영체제가 이를 제공한다.
- 문자 단위 입/출력 함수
EOF란 End Of File의 약자로 파일의 끝을 표현하기 위해 정의된 상수이다. 위의 함수가 파일이나 콘솔의 출력으로 EOF를 반환하게 되면 파일이나 콘솔로부터 더 이상 입력 받을 것이 없다 라는 의미를 갖는다. 그렇다면 EOF를 반환하는 시기는 다음과 같다.
함수 호출의 실패할 경우
컨트롤 + z / 컨트롤 + d 키가 입력될 경우
문자를 입력 받는 함수인데 반환 형이 정수 int 형인 이유는? 컴파일러에 따라 char을 unsigned char로 처리하는 경우가 존재한다. 그런데 EOF 라는 값은 -1로 정의되어 있는데 char을 unsigned char로 처리하는 컴파일러는 EOF에 대한 처리가 불가능하다. 그렇기 때문에 같은 정수 타입인 int로 반환한다.
- 문자열 단위 입/출력 함수
기존의 scanf 함수 등은 공백을 포함한 문자열을 입력 받기에 있어서 크게 제한이 되었다. (공백을 기준으로 입력을 나누기 때문)
- 표준 입/출력 버퍼
표준 입/출력 함수를 통해서 데이터를 입/출력하는 경우, 해당 데이터들은 운영체제가 제공하는 메모리 버퍼를 꼭 통과하게 되어 있다. 메모리 버퍼는 데이터를 임시로 저장해 놓는 메모리 공간인데, 이런 저장하는 작업을 버퍼링 이라고 한다.
키보드로 데이터를 입력하면(문자열 입력 후 엔터를 칠 경우) 해당 데이터들은 입력 버퍼로 전송되어 저장되고(버퍼링), 그 이후에 프로그램으로 데이터들이 전송이 된다.
버퍼링을 하는 이유?
프로그램 연산(CPU 연산)에 비했을 때 I/O 장치들 과의 I/O 작업은 상당히 시간이 걸리는 작업이다. 즉, 데이터를 읽어오는데 걸리는 시간이 CPU의 연산 처리 속도보다 훨씬 느리다. 그렇기 때문에 CPU는 그러한 느린 데이터 입출력 처리를 기다리고 있어야 하는데 데이터를 읽을 때마다 조금씩 전송을 하는 구조로 진행되면 데이터 전송의 효율성이 떨어진다. 그렇기 때문에 중간에 메모리 버퍼를 두고 데이터를 한데 묶어서 보내면 빠르고 효율적인 데이터 전송이 될 수 있다.
- 출력 버퍼와 입력 버퍼 비우기!
출력 버퍼를 비운다는 것은 출력 버퍼에 저장된 데이터가 버퍼를 떠나서 목적지로 이동되는 것을 이야기하는데, 이러한 역할을 하는 함수가 존재하는데 다음과 같다.
위 함수는 파일을 대상으로도 버퍼 비우기가 가능하고, 출력 버퍼를 비우는 일은 많이 존재하지는 않는다.
반면에, 입력 버퍼를 비운다는 것은 출력 버퍼와는 다르게 데이터의 소멸을 의미한다. fflush 함수를 이용하여fflush(stdin); 과 같은 형태로 호출하면 입력 버퍼는 비워지거나/비워지지 않거나 보장할 수 없는 결과를 나타낸다. (Windows 계열의 컴파일러의 경우는 입력 버퍼를 지워 준다고 한다.)
입력 버퍼를 비우기 이전에 입력 버퍼를 비워야 하는 경우에 대한 예제이다.
먼저, 6번 라인에서 str1의 크기를 10 바이트로 지정해주었고, 10번 라인에서 str1에 문자열을 대입하는데 9자리의 문자를 대입한다. 9자리라고 함은 문자열 9자리와 NULL 문자 1바이트를 고려한 것이다. 그러나 입력될 때에는 “abcdefghi\0\n” 이 입력되고 입력 버퍼에 들어가게 된다. (fgets함수의 ‘\n’이 입력될 때까지 읽어 들이는 특성 상) 그래서 10번 라인에서는 입력한 “abcdefghi” 문자열에 ‘\0’ 문자가 합쳐져서 입력으로 str1에 저장된다. 그리고 13번 라인에서 fgets 함수가 호출되는데 이 때 입력 버퍼에 남은 ‘\n’ 문자를 읽어버리고 바로 호출이 끝나게 된다. 그렇기 때문에 실행 결과에서는 str2에 ‘\n’만 저장된 결과가 나타난 것이다. 이러한 경우 str1의 저장 이후 입력 버퍼를 비웠더라면 다음 문자열 입력을 받을 수 있었다. 이것이 입력 버퍼 비우기의 필요성이다.
입력 버퍼를 비운다는 것은 문자들을 읽어 들이면 지워진다, 즉 비워진다. 다음과 같은 함수로 입력 버퍼를 지울 수 있다.
23번 라인에서 한 문자씩 읽는데 그 읽은 것이 ‘\n’ 개행 문자일 경우 탈출하게 된다. 즉, 개행 문자까지 버퍼로부터 문자를 읽음으로써 버퍼가 비워진다.
- 문자열의 길이를 반환 : strlen
일단, size_t는 typedef unsigned int size_t; 로 자료형 재정의가 되어 있다.
- 문자열의 복사 : strcpy
strcpy는 src의 문자열을 dest에 복사한다. strncpy의 경우에는 src의 문자열을 dest에 복사하되, n 크기만큼 복사한다. 단, strncpy의 경우 마지막 문자가 NULL인지에 대한 검사는 하지 않고 주어진 n만큼만 복사를 한다. 즉, 복사된 문자열의 끝에서 NULL에 대한 처리를 진행하지 않기 때문에 직접 NULL 처리를 해줘야 한다. 이후에 기재되는 모든 n이 들어가는 함수는 NULL처리가 진행되지 않는 공통점을 가지고 있다.
- 문자열 연결 : strcat
Dest 문자열 뒤에 src 문자열을 붙이고 그 값을 dest에 저장한다. 앞 문자열의 NULL 문자를 없애고 그 자리부터 뒷 문자열이 시작된다.
- 문자열 비교 : strcmp
- 이외의 문자열/수 변환 함수
'컴퓨터 언어 정리 > C 언어' 카테고리의 다른 글
17 파일 입출력 (0) | 2020.10.13 |
---|---|
16 구조체 (0) | 2020.10.12 |
14 함수 포인터와 void 포인터 (0) | 2020.09.23 |
13 다차원배열 및 포인터의 관계 (0) | 2020.09.21 |
12 포인터의 포인터 (0) | 2020.09.15 |