해결된 질문
작성
·
115
1
안녕하세요, 강의 13.4에서 fscanf와 fgets와 같은 함수들의 구체적인 사용에 관해 듣다보니 의문이 생겨 질문 남깁니다.
해당 함수들 모두 인자로 stdin 같은 값(매크로?)을 받아들이는데, 설명 상 우리가 키보드로 입력하는 값을 받아들이게 해주는 역할로는 이해가 가나 정확하게 무슨 값이라고 불러야 할 진 잘 모르겠습니다.
stdin, stdout, stderr 이들은 무슨 값이라고 해야하나요? 이들의 정확한 역할은 무엇인가요?
답변 2
1
안녕하세요? 질문&답변 도우미 durams입니다.
따배씨는 강의에서 fd나 버퍼에 대해 아주 깊게 다루지는 않으며, C 기초 강의의 내용을 벗어나는 주제이기도 합니다. 하지만 궁금하신 점에 대해 충분히 답해드리는 것도 중요한 일이라고 생각하기 때문에 최대한 풀어서 설명드리겠습니다.
stdin
, stdout
, stderr
은 각각 표준 입력 스트림, 표준 출력 스트림, 표준 에러 스트림이라고 합니다. 본 강의의 입출력에 대해 다루는 부분에서 스트림이라는 단어를 교수님께서 '정보가 흘러가는 것'이라고 간단하게 설명하신 적이 있습니다.
보다 정확하게 표준 입출력에서의 스트림이란, 내부적으로 파일 디스크립터(fd)와 버퍼를 한데 묶어서 추상화시킨 객체라고 생각하시면 될 것 같습니다. 타입은 FILE
구조체로, 강의에서도 소개된 바가 있습니다.
버퍼에 대해서는 강의에서 여러번 다루어서 익숙하실 것이라고 생각합니다. 파일 디스크립터는 생소하실 수도 있는데, 간단히 말해서 '특정한 파일을 가리키는 고유한 정수값'이라고 생각하시면 될 것 같습니다.
요약하자면, 스트림이란 무언가 파일에 입출력하기 위한 정보를 모아놓은 것이라고 할 수 있습니다. C언어에서는 대부분의 입출력 상황에서 이러한 스트림 방식을 사용합니다. (특수한 경우에는 프로그래머가 목적을 위해 자신만의 입출력 함수를 구현하여 사용할 수도 있습니다)
일반적으로는 저희가 C에서 입출력을 하고 싶을 때 #include <stdio.h>
로 헤더 파일을 포함하게 됩니다. stdin
, stdout
, stderr
은 이 파일에 선언되어 있으며, 프로그램과 그 생명 주기를 같이하게 됩니다. 정적 변수가 프로그램의 시작부터 끝까지 유지되는 것을 떠올리시면 될 것 같습니다.
위에서 스트림이 fd와 버퍼를 합친 것이라고 말씀드렸지만, 사실 입출력에는 버퍼링을 동반하지 않는 경우도 있습니다.(이런 것을 unbuffered i/o라고 합니다)
대표적인 것이 stderr
입니다. 일반적인 경우, 에러 메시지 출력 등의 목적을 위해 stderr
은 버퍼를 거치지 않고 지연 없이 즉각적으로 수행됩니다.
stdout
은 기본적으로 버퍼링을 사용하기 때문에, 에러 발생 시 버퍼에 남아있는 내용이 섞이거나 순서가 뒤바뀔 수 있습니다. 깔끔한 에러 출력을 원할 때에는 stderr
를 사용합니다.
여기서 왜 파일이라는 단어가 나오는지 궁금해하실수도 있습니다. '지금까지 printf
, scanf
같은 표준 입출력 함수 쓸 때는 파일이 아니라 검은색 cmd 창에서 했는데?' 라는 의문이죠.
"유닉스 기반 환경에서는 모든 것이 파일이다" 라는 말이 있습니다. 실제로 리눅스에서는 프로그램, 디렉토리, 컴퓨터에 마운트된 장치, 네트워크 소켓까지 모든 것이 파일 시스템 내에 하나의 파일로 존재하며 사용자가 입출력의 대상으로 삼는 터미널도 예외가 아닙니다.
윈도우 환경과 유닉스 기반 환경이 완벽히 동일하지는 않지만, 표준 입출력의 개념은 비슷합니다. 두 환경 모두 스트림 객체를 통해 터미널에 대한 입출력을 수행합니다.
표준 출력 스트림이란 터미널에 대한 파일 정보와 출력에 필요한 버퍼를 합쳐놓은 것입니다. printf
는 표준 출력 스트림에 대해 동작하는 함수로, 사용자가 입력한 문자열을 터미널이라는 파일에 write(쓰기)하게 됩니다. 그러면 사용자가 눈으로 보고있는 터미널에 문자열이 출력되는 것을 확인할 수 있습니다.
위 내용의 이해에 될지 모르겠지만, 두 함수를 비교해보겠습니다.
scanf
는 표준 입력 함수로, 사용자로부터 표준 입력 스트림을 통해 입력받습니다. 그와 반면 fscanf
는 사용하는 스트림이 정해져 있지 않으며, 어떤 스트림을 사용할 것인지 전달해줘야 합니다.
즉, scanf
는 fscanf
의 특수화된 형태라고 생각할 수 있으며, scanf
는 fscanf(stdin, ...)
과 동일합니다.
종합하자면, stdin
, stdout
, stderr
는 편리한 입출력을 위해 C 표준 라이브러리에서 제공하는 추상화된 객체입니다. 이들을 통해 프로그래머는 내부 입출력 구현에 크게 신경쓰지 않고 고수준에서 원하는 입출력 동작을 수행할 수 있습니다.
더 궁금한 점이 있으시다면 질문주세요.
1
안녕하세요, 인프런 AI 인턴입니다. 새싹비빔밥님.
stdin
, stdout
, stderr
는 C 프로그래밍에서 표준 입출력을 담당하는 파일 포인터입니다. 이들은 각각 표준 입력, 표준 출력, 표준 오류를 의미하며, 프로그램이 실행되는 동안 자동으로 초기화되고 관리됩니다. 이를 통해 파일 입출력 함수와 유사하게 작동하지만, 실제 파일이 아닌 프로세스의 입출력 흐름을 관리합니다.
stdin
(Standard Input): 이는 표준 입력을 담당하며, 기본적으로 키보드 입력을 받습니다. scanf
, fgets
등 입력 함수들이 이 표준 입력을 통해 데이터를 읽어 옵니다.
stdout
(Standard Output): 이는 표준 출력을 담당하며, 기본적으로 화면에 출력합니다. printf
함수는 이 표준 출력을 통해 화면에 데이터를 표시합니다.
stderr
(Standard Error): 이는 표준 오류 출력을 담당하며, 오류 메시지를 출력할 때 사용합니다. 기본적으로 화면에 출력되지만, stdout
과는 독립적으로 동작하여 디버깅 및 오류 로그를 따로 처리할 수 있게 합니다.
이러한 표준 입출력 스트림은 운영체제가 관리하며, 프로그램 실행 시 자동으로 초기화되므로, 별도의 설정 없이도 사용 가능합니다.
이해를 돕기 위해 관련 게시물의 URL을 첨부하니 참고해 보세요:
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
우와 자세한 설명 정말 감사합니다 !! 똑똑하시군요...!