OS-level input buffer..에 존재하는 모든 데이터를 flush시키기

leolo의 이미지

#include <stdio.h>
int main()
{
int c;
while((c = getchar()) != '\0'){
putchar(c);
}
return 0;
}
이렇게 일반적으로 데이터를 입력받아 사용하는데요..

만약에,

c = getchar();
putchar(c);

로 단순히 코딩을 하고 실행시켜서 값을 입력하는데 있어서..
ABCD 를 입력하면 A만 출력이 되겠죠.
여기서, BCD는 OS-level input buffer에 존재한다고 들었는데요.
여기까지의 질문 내용에 문제가 없는지 일단 좀 가르쳐 주세요..

다음으로 OS-level input buffer라는 것이 무엇인지 알려주세요.
대충은 알겠습니다. input이 있으면 output도 있겠죠. 물론, 시스템에 따라
그 사이즈도 다르겠죠.

마지막으로 OS-level input buffer에 들어있는 나머지 데이터를 없에는
이식성을 가지는 방법은 없는지 알고 싶습니다.
그러니까?
c = getchar();
putchar(c);
요 코드 다음에 어떻게 하라.. 정도로 알려주시면 더욱 감사하겠습니다.

moian의 이미지

fflush( stdin );

정도로도 input 버퍼에 입력된 쓰이지 않은 데이타를 제거 가능할것 같습니다.

eungkyu의 이미지

OS레벨이기보단 C의 standard IO libarary의 버퍼에 들어가겠죠. 물론, OS레벨에도 버퍼가 있긴 하겠지만, 그건 또 다른 문제고.
왜 그 버퍼를 비우려 하시는지는 모르겠지만, 프로그램이 끝나면 알아서 비워집니다 -_-;; 어떤 상황에서 왜 비우려 하시는지..

leolo의 이미지

eungkyu wrote:
OS레벨이기보단 C의 standard IO libarary의 버퍼에 들어가겠죠. 물론, OS레벨에도 버퍼가 있긴 하겠지만, 그건 또 다른 문제고.
왜 그 버퍼를 비우려 하시는지는 모르겠지만, 프로그램이 끝나면 알아서 비워집니다 -_-;; 어떤 상황에서 왜 비우려 하시는지..

아래 부분의 내용을 확인하기 위해서 질문 드린 것입니다. 음.. 그렇네요. 라이브러리 버퍼겠죠. 프로그래이 끝나면 당연히 없어지겠죠.
저는 코드에서 버퍼에 남아있는 것을 플러쉬시키고 다시 받기 위해서 질문 드린 것입니다... ^^

Q 12.26
입력을 방출(flush)시킬 방법이 있을까요? 즉 사용자가 미리 입력한 입력을 무시해서, 다음 프롬프트를 출력할 때 이 입력이 출력되지 않도록 하고 싶습니다. fflush(stdin)을 쓰면 될까요?
A
fflush()는 출력 스트림에 대해서만 동작합니다. ``flush''라는 단어가 `버퍼링된 출력을 (무시하는 것이 아니라) 내보낸다'는 의미이므로 입력 스트림의 입력을 무시하는 기능과는 전혀 상관없는 함수입니다.
아직 읽지 않은 문자들을 stdio 입력 스트림에서 무시하는 표준 방법은 존재하지 않습니다. 일반적으로 아직 읽히지 않은 입력은 OS 수준의 입력 버퍼에 존재하기 때문에 이를 해결할 방법은 없습니다. 해결책은 \n이 나오기 전까지의 문자를 읽어서 무시하거나 curses 루틴인 flushinp()를 사용하거나, 시스템 의존적인 방법을 쓰면 됩니다. 덧붙여 질문 19.1, 19,2도 참고하시기 바랍니다.

참고
ISO Sec. 7.9.5.2; H&S Sec. 15.2.

실력이 있으면 삶이 편하다... 영차 영차...

dhjung의 이미지

leolo wrote:
만약에,

c = getchar();
putchar(c);
마지막으로 OS-level input buffer에 들어있는 나머지 데이터를 없에는
이식성을 가지는 방법은 없는지 알고 싶습니다.
로 단순히 코딩을 하고 실행시켜서 값을 입력하는데 있어서..
ABCD 를 입력하면 A만 출력이 되겠죠.
여기서, BCD는 OS-level input buffer에 존재한다고 들었는데요.

아직 읽히지 않은 BCD가 존재하는 곳은 *일반적*으로 OS-level input buffer라고 하기보다는,
C Library Buffer라고 하는게 더 정확할 듯 싶습니다..
물론 일반적이지 않게, setvbuf()로 unbuffered로 설정할 수도 있지만요...

예를 드신게, getchar()와 같은 stdio, 즉 Stream I/O인 경우를 물어보셨으니 그에 대해 설명드리면...
Stream I/O는 다음과 같은 buffer 구조를 통해서 실제 데이타를 read/write하게 됩니다..

(Application) <--> (C Library Buffer) <--> (System Buffer) <--> (Device)

말씀하신데로, ABCD를 입력하게되면, "Input device"인 키보드로부터 ABCD가 입력되고, 이 ABCD값은 "System Buffer"를 거쳐,
"C Library Buffer"에 저장이 됩니다... 즉, 실제 getchar()는 "C Library Buffer"에서 읽어드리게 되는겁니다...

여담으로 output에 관련된 것이기는 하지만, fflush(3C)은 "C Library Buffer"의 내용을 "System Buffer"로 flush를 시키는 것이며,
sync(1)과 sync(2), fsync(3C)는 "System Buffer"의 내용을 "Device", 즉 Disk에 flush 시키는 것입니다.
(물론, sync(1)과 sync(2)는 그밖의 작업을 더 수행합니다.)

leolo wrote:
input이 있으면 output도 있겠죠.

output buffer가 input과 분리되어 존재하기보다는 하나의 buffer를 공유해, I/O가 같이 일어날 것으로 생각됩니다..

leolo wrote:
물론, 시스템에 따라
그 사이즈도 다르겠죠.

*순수한* 버퍼만의 사이즈는 512K(block사이즈)의 배수로, 리눅스와 솔라리스의 경우 8K로, AIX의 경우 4K로 알고 있습니다...

leolo wrote:
마지막으로 OS-level input buffer에 들어있는 나머지 데이터를 없에는
이식성을 가지는 방법은 없는지 알고 싶습니다.

이식성을 가지는 방법은 없습니다.
즉, C 표준에 input buffer를 clear시키는 방법에 대해서는 언급하고 있지 않습니다.
정 하고 싶으시다면, 위에 적으신 예제처럼, getchar()로 EOF까지 읽은뒤, 혹은 다른 방법으로 읽은 데이타를 버리는 수밖에 없습니다.


--------------------------
Donghyun Jung

eungkyu의 이미지

leolo wrote:
eungkyu wrote:
OS레벨이기보단 C의 standard IO libarary의 버퍼에 들어가겠죠. 물론, OS레벨에도 버퍼가 있긴 하겠지만, 그건 또 다른 문제고.
왜 그 버퍼를 비우려 하시는지는 모르겠지만, 프로그램이 끝나면 알아서 비워집니다 -_-;; 어떤 상황에서 왜 비우려 하시는지..

아래 부분의 내용을 확인하기 위해서 질문 드린 것입니다. 음.. 그렇네요. 라이브러리 버퍼겠죠. 프로그래이 끝나면 당연히 없어지겠죠.
저는 코드에서 버퍼에 남아있는 것을 플러쉬시키고 다시 받기 위해서 질문 드린 것입니다... ^^

standard io가 다루는 것은 stream입니다. stream은 물줄기처럼 밀려오고(입력) 또한 밀려나가는(출력) 것이죠. 물줄기와 현재 처리하는 위치가 있을 뿐이죠. 중간을 뚝 짤라버리는 행위는 스트림 처리에서 매우 이상한 행동입니다. 게다가, 버퍼라는 것은 standard library에서 성능을 위해서 제공하는 것으로서, 그 라이브러리를 사용하는자의 입장에서는 어느정도 transparency하게 내부적으로 제공되는 것입니다.

설사 입력 버퍼를 지우는 함수가 존재한다고 합시다. 지금이야 손으로 입력을 받는 프로그램이라서 그런 식으로 생각해도 말이 되는 듯 합니다. 하지만 상대가 파일이 되면 (progarm < file 이렇게 실행하면) 버퍼의 한계가 불명확해지고 버퍼를 비우면 얼마나 지워질지 짐작하기도 힘듭니다. (프로그램이 제대로 동작하지 않을 수 있다는 뜻입니다) 즉, 버퍼를 비우는 행위는 스트림 처리에서 매우 이상한, 말도 안되는 행동일 뿐더러 standard io library가 애써 만들어놓은 transparency도 깨뜨릴 수 있는 행위입니다. standard io library 내부를 다루는 프로그램이 아니라면, 버퍼를 건드리는 행위는 자제해야 합니다.

개념을 바꿔서 버퍼를 비운다보다는, 쓸데없는 입력을 무시한다로 생각하시면 프로그래밍하기가 편해집니다. 원래 스트림이 그런겁니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.