계속 무한 loop가 되네요~ 고수님들 해결해 주세요~~

ins878의 이미지

안녕하세요. 참 이상해서 이렇게 질문을 드립니다.


#include <stdio.h>

int main()
{
	int a;
	
	do
	{
		printf("quit : 1\n");
		scanf("%d", &a);

	}while(a != 1);

	return 0;
}

위 소스코드를 보면 숫자 1을 입력하면 loop 가 타출되잖아요. 그리고 1이 아닌 다른 키를 누르면 계속 loop를 돌면서 값(scanf)을 받고요...
근데 숫자 1이 아닌 다른 숫자를 누르면 정상적으로 작동하는데, 이상하게 문자를 입력하면 값(scanf)을 받지 않고 무한 loop를 돌더군요.

위 소스코드가 잘못된 건가요.
1이 아닌 어떠한 키를 눌러도 값(scanf)를 받으면서 loop를 돌게 하려면 어떻게 해야하는지...
고수님들 가르쳐 주세요...

ed.netdiver의 이미지

%d의 압박...^^;

--------------------------------------------------------------------------------
\(´∇`)ノ \(´∇`)ノ \(´∇`)ノ \(´∇`)ノ
def ed():neTdiVeR in range(thEeArTh)

sozu의 이미지

#include <stdio.h> 
#include <string.h>

int main() 
{ 
   char a[255]; 
    
   do 
   { 
      printf("quit : 1\n"); 
      scanf("%s", a); 

   }while(strcmp(a, "1")); 

   return 0; 
}

%d를 해놓고 문자열을 입력하시면 않되죠.. :D

-----------
청하가 제안하는 소프트웨어 엔지니어로써 재미있게 사는 법
http://sozu.tistory.com

unipro의 이미지


#include <stdio.h>

int main()
{
	int a;
	
	do
	{
		printf("quit : 1\n");
		scanf("%d", &a);

	}while(a != 1);

	return 0;
}

scanf 의 %d 는 정수의 10진수 형태를 입력받습니다.
이 형태가 아닌 값을 넣으면 읽지 못합니다.
문제는 입력버퍼에 그 값이 계속 남아서 다음번에도
그것을 읽으려고 시도하며 같인 이유로 읽지 못합니다.
여기서 무한 반복이 발생됩니다.

내 블로그: http://unipro.tistory.com

ins878의 이미지

1이 아니면 오류메시지를 뛰우고 싶은데, 그렇다면... 어떻게 해야 하죠?
문자로 읽어 들어야 하는가요...?
아니면... 다른 방법이라도~~~

lacovnk의 이미지

scanf의 리턴값을 사용하면 될 것 같습니다만..

Quote:
RETURN VALUE
These functions return the number of input items assigned, which can be fewer than provided for, or even zero, in the event of a matching failure. Zero indicates that, while there was input available, no conversions were assigned; typically this is due to an invalid input character, such as an alphabetic character for a `%d' conversion. The value EOF is returned if an input failure occurs before any conversion such as an end-of-file occurs. If an error or end-of-file occurs after conversion has begun, the number of conversions which were successfully completed is returned.

화이팅이요! :)

cinsk의 이미지

scanf()를 쓰는 것은 바람직하지 않습니다. 개인적으로는 쓸모가 전혀 없는 함수라고 생각하고 있습니다. 물론 모든 scanf 시리즈가 다 그렇다는 것은 아닙니다. sscanf(), fscanf()는 매우 좋은 함수이지만, stdin에서 입력을 받을 때, scanf()를 쓰면, 입력에 scanf()가 원하지 않는 내용이 있을때, 질문하신 것처럼 엉뚱한 결과를 가져오기도 합니다.

stdin에서 입력을 받기 위해서는 대개 다음과 같은 함수를 씁니다:

getchar()
fgets()
readline() /* GNU extension */

그리고 문자열이 아닌, 다른 수치 타입을 원한다면, strtok(), strchr() 등을 써서 적당히 끊어 낸 다음, strtol(), strtoul(), strtoll(), strtoull(), strtod(), strtof(), strtold() 등을 써서 변환하면 됩니다.

ins878의 이미지

답변 감사드립니다. 잠시 다른 곳에 갔다오느냐... 못봤네요~~
많이 쓰이는 scanf() 가 제가 생각했던 것보다는 기대 이하의 기능에 좀 아쉽네요... (그렇다고 꼭 나쁘다고 말하는 것은 아니고요~)
제가 활용을 잘 못해서 그러겠죠~^^
답변 감사드립니다.
몰랐던 사실을 알았네요~

익명 사용자의 이미지

Quote:

scanf의 리턴값을 사용하면 될 것 같습니다만..

안됩니다. 만약 %d로 숫자값을 읽고 싶은데 문자를 입력할 경우에는 무한루프 뺑뺑이를 돌게 됩니다. scanf가 입력 스트림에 있는 일치하지 않는 데이터(이 경우에는 문자)를 읽지 않기 때문에, 계속 문자는 입력 스트림에 남아있게 되고 무한 뺑뺑이가 되는 것입니다. 이걸 해결하기 위해서는 적절하게 입력 스트림을 비워줘야 하는데 유감스럽게도 fflush(stdin)은 표준이 아니며 입력 스트림을 모두 비우는 행위 자체가 상당히 골때리는 일입니다(입력스트림이 파이프거나 리다이렉션된 파일같이 한꺼번에 들어오는 데이터일 경우에는 아직 읽지못한 데이터가 모조리 날라갑니다).

가장 나은 방법은 위의 cinsk님이 말씀하신 것처럼 fgets로 한줄 전체를 읽고 그것을 sscanf로 해석하는 것입니다.

char buf[4096];
int i, ret;

do {
    printf("Input Number : ");
    if ( !fgets(buf, 4096, stdin) ) { ret = -1; break; }
    ret = sscanf(buf, "%d", &i);
} while ( ret != 1 );

댓글 달기

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