c언어 getchar와 putchar 관련해서 궁금한게 있습니다

phi의 이미지

이제 막 c언어 공부를 시작했는데
c언어 기초 플러스라는 책에서 입력 유효성 검사와 관련한 내용을 진행할때
사용자가 입력한 값이 정수값인지 아닌지를 구분하는 함수를 제작하는데

int get_int(void)
{
int input;
char ch;

while (scanf("%d", &input) != 1)
{
while ((ch = getchar()) != '\n')
putchar(ch);

printf(": 정수가 아닙니다.\n정수값을 입력하시오: ");
}

return 0;
}

이런식으로 구성된 함수입니다.

여기서 먼저 while의 조건에 속한 scanf함수에 값을 입력하면
그 값이 정수인지 아닌지 리턴값으로 판단하고, 올바른 정수값이 아니라면 다음 while로 넘어가는데

이때 2번째 while함수에서 getchar가 왜 input값을 받는건가요?

그리고 getchar와 putchar는 문자값 하나만 받는다고 알고있습니다.
위 get_int함수의 input값이 test라면
getchar가 t, e, s, t 각각의 경우에 대응해서 ch에 값을 대입하고 putchar가 ch값을 출력하는것 같은데
어떤 방식으로 이게 실행되는건지 잘 모르겠습니다.

일단 test라는 값을 입력하면 첫글자인 t만 getchar가 받아들이고 나머지 값은 버퍼에 남겨두는건가요?
그리고 t가 ch에 대입되고 그런 ch를 putchar가 출력하고.. 이 부분이 책에는 주석으로 잘못된 입력을 폐기한다고 적혀있더라구요.
이렇게 한번 루프가 끝나고 다시 조건을 확인할 때, 버퍼에 남아있던 est값의 첫글자인 e를 받아들이고 루프를 계속하는건가요?

위 3문장이 제가 최대한 생각해본건데, 맞는건지 의문입니다.

즉, 제가 궁금한건 두가지인데
1. 위 get_int함수의 두번째 while에서 getchar가 왜 input값을 받는건가요?
2. 두번째 while함수의 진행 과정이 어떻게 되는건가요?

c언어 기초 플러스라는 책이 좋다고해서 이거로 공부중인데
7장에서 getchar와 putchar가 갑자기 나오더니 8장에서 버퍼개념이 나오고 나서부터 대혼란..
그래도 재밌어서 다행이네요 ㅎㅎ

peecky의 이미지

생각하신 게 맞습니다.

프로그램 실행과정은

scanf() 실행.
사용자가 test<엔터> 입력. 버퍼에 "test\n" 저장됨.
%d에 해당하는 문자가 버퍼에 없으므로 scanf()는 0을 리턴. 버퍼는 계속 "test\n" 으로 남아있음.
getchar() 실행. ch는 't'가 되고, 버퍼는 "est\n" 이 남아있음.
putchar('t') 실행.
getchar() 실행. ch는 'e'가 되고, 버퍼는 "st\n" 이 남아있음.
... 중략 ...
getchar() 실행. ch는 '\n'이 되고, 버퍼는 비워짐.
printf() 실행.
scanf() 실행.
... 후략

이렇게 됩니다.

1. 버퍼를 비우고 새로운 입력 값을 scanf()로 받기 위함입니다.
2. 위의 내용 참고.

phi의 이미지

친절하게 설명해주셔서 감사합니다!
getchar가 test\n을 받는것도 버퍼에 그대로 남아있어서 그런거군요!

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.