C Language [핵심정리] - 18
1. 입력값을 문자열에 저장
scanf 함수에서 서식지정자로 %s를 사용하면 입력 값을 배열 형태의 문자열에 저장할 수 있습니다.
일반 변수의 입력값을 받을 때와는 달리 배열 앞에는 &(주소연산자)를 사용하지 않습니다. 왜냐하면 배열도 포인터처럼 주소를 담고 있기 때문이죠. 만약 scanf 함수에서 서식지정자 %s로 문자열을 저장할 때 입력된 문자열에 공백이 있다면 공백 직전까지만 저장됩니다.
그래서 공백까지 포함하여 입력받고 싶다면 scanf 함수에서 서식지정자를 %[^\n]s의 형태로 지정하면 공백까지 포함하여 문자열을 입력받을 수 있습니다.
2. EOF
EOF는 End Of File의 약자이며, 더 이상 값을 읽을 수 없는 상태를 나타냅니다.
Windows에서는 Ctrl + Z 키의 입력을 EOF로 정했습니다.
EOF는 <stdio.h>파일에 정의되어 있으며 정수는 -1 입니다. 보통 EOF는 파일 처리 함수가 실패했을 경우 반환됩니다.
+ Visual Studio 컴파일러일 경우
보안상의 문제로 scanf_s 함수 사용을 권장하는데요. 이 경우에는 scanf 함수와 형태가 조금 달라집니다.
scanf_s는 해당 변수의 크기를 명시해줘야 합니다. 그런데 경고가 뜨네요. 한번 봐볼까요?
크기 불일치라고 하네요. 이 경우 크기를 일치시키면 되겠죠? char 자료형 또한 일종의 정수 자료형임을 기억해주세요.
이처럼 형변환을 통해 자료형을 일치시키니 워닝(경고)를 의미하던 녹색줄이 사라졌습니다~ 참 간단하죠?
3. 입력값을 문자열 포인터에 저장
배열 형태에 입력값을 저장했는데 포인터 형태를 건너뛰게 된다면 아쉬움이 남겠죠? 그래서 준비했습니다.
일단 잘못된 예시를 보여드릴게요.
이처럼 해당 코드는 scanf 함수 때문에 발생하는 문제를 제외하고는 에러, 경고가 발생하지 않기 때문에 전혀 문제가 없는 것처럼 보입니다. 하지만 결과를 보면 알 수 있듯이 당연히 문제가 있습니다. 디버그를 통해 알아보면 [0xC0000005:0x00007FF666DAED70 위치를 기록하는 동안 액세스 위반이 발생]했다는 걸 알 수 있습니다.
이처럼 경고와 에러 메세지가 뜨지 않았지만 실제로는 에러가 발생하는 경우가 있습니다. 그러니 여러분들도 디버그를 하는 습관을 들이시면 좋을 겁니다.
그래서 입력값을 문자열 포인터에 저장하려면 다음과 같이 문자열이 들어갈만한 공간을 따로 만들어야 합니다.
이 문자열 포인터 또한 공백 직전까지만 저장됩니다.
+ 가끔씩 입력값을 크기보다 더 입력할 수 있는 경우가 있습니다. 그 이유는 컴파일러나 운영체제에 따라 배열이 선언된 메모리나 동적으로 할당한 메모리 뒷부분에 공간이 더 있을 수 있기 때문입니다. 그래서 한 두개?정도는 더 입력할 수 있습니다. 하지만 많은 문자열을 입력할 경우 다른 데이터가 있는 공간까지 침범하게 되므로 에러가 발생합니다. 다른 프로그래밍 언어들과 달리 C언어는 다른 메모리 공간 침범을 신경써주지 않습니다. 그래서 모든 부분을 프로그래머가 제어해야합니다. 그렇기에 C언어로 프로그램을 만든다면 항상 입력값과 크기 부분을 신경써야 합니다.
4. 문자열을 여러 개 입력
이번에는 공백으로 구분된 문자열 [두 개]의 입력을 받아오겠습니다.