• [컴퓨터] 개초보의 C프로그래밍 질문 두번째.2012.03.28 PM 05:56

게시물 주소 FONT글자 작게하기 글자 키우기

C언어입니다.

검색해보니 goto는 가급적 쓰지 말라고만 되어있길래 질문을 좀 올려봅니다.

scanf로 입력받은 값을 가지고 if문을 돌리다가 알맞은 값이 아니면 처음 입력받는 곳으로 돌려보내는 코드를

goto를 이용해서 짜보았습니다.
----------------------------------------------------------------------------------------
INP_S:;
printf("A또는 B를 입력하세요. : ");
scanf("%c",&selec);
printf("숫자를 입력하세요 : ");
scanf("%d",&num_1);
......................................중간 코드 생략..............................
if (selec=='A')
......................................중간 코드 생략...............................
else
{
printf("잘못입력되었습니다! 다시 입력하십시오.\n\n");
goto INP_S;
}
----------------------------------------------------------------------------------------
대강 이런 식입니다. 그런데 입력받은 값이 else에 걸려 goto에 걸리는 경우 레이블로 돌아가는것까진 문제가 없는데
다시 scanf로 입력을 받지않고 다음 문장으로 넘어가버립니다.

대략 다음과 같습니다.
----------------------------------------------------------------------------------------
A또는 B를 입력하세요. : C
숫자를 입력하세요 : 2
....생략....
잘못입력되었습니다! 다시 입력하십시오.

A또는 B를 입력하세요. : 숫자를 입력하세요. :
----------------------------------------------------------------------------------------
보시면 다시 입력하라고 나온다음에 A또는 B를 입력받는 부분을 건너 뛰고 숫자 입력으로 건너가버립니다.

이 코드 외에도 두번째 입력을 받는 것이 아니고 바로 결과값을 출력하는 코드의 경우에는

입력하라는 메세지가 무한으로 출력되는 문제가 발생합니다.

무엇이 잘못된건가요.. 어떻게 고쳐야 되는지 알려주세요.. ㅠ
댓글 : 20 개
차라리 while문을 쓰셔서 일정 조건이 맞을시 에만 루프에서 벗어나게 짜는것을 추천합니다. 여러 프로그램들이 보통 그렇게 짜여있습니다.
입력부를 함수로 빼면 가능하지 않을까요..?
case 문이 사용하기 더 편할거같아요
스파게티 코드(가독성도 떨어지고 유지보수도 힘든 코드)를 만들어주는 훈훈한 고투쨔응
goto를 썼을때 이런 현상이 발생하는건 C컴파일러의 오류인건가요 아님 제가 멍청한건가요 ㅠ
바론君//보통은 설계미스 goto문 쓰면 설계가 눈 아픕니다.
scanf 는 문자입력값이 남아있어서 그런거 같습니다 fflush등을 이용해서 비워보세요
  • Hanon
  • 2012/03/28 PM 06:16
fflush쓰면 될거같은데

#include <stdlib.h> 추가하시고

fflush(stdin); 해보세용
goto자체가 잉여..이면서도 goto 쓰는 것 자체가 종료조건 걸기가 나빠서.......
for나 while 쓰는게 훨나은듯요.
그리고 위에 코드를 다안써주셔서 잘모르겠는데 저게 제대로나올려면 변수selec를 초기화해주셔야됩니다.
좀더 근본적인 문제로는..
scanf("%c",&selec); 여기에 있는 것 같네요.
%c의 경우 하나의 글자만 가져와야 하는데, stdin 버퍼상에서는 엔터 문자 (\n)도 남아 있기 때문에 건너띄는 것처럼 보이는 것 같아요.
힝~-~님 말씀대로 %s 를 써보심이???
답변해 주신 분들 정말 감사합니다! goto는 안쓸게요 ㅠ

fflush를 적재 적소에 박아주니까 해결이 되네요 ㅠㅠ 감사합니다
여담이지만 결국 컴파일러 내부에서 for, while, switch문 모두 GOTO로 변경 된답니다.^^;
kozzang732// 오호 그렇군요!!
kozzang732//뭐.. 결국 모든 코드는 asm으로 변환되고 asm 내엔 for, while이 없으니까요.

그래도 goto를 쓰면 그나마 C 스럽게 짤 수 있던 코드가 asm 수준으로 내려가던것 같네요 ㅠㅠ
goto 를 무조건 쓰면 안 되는게 아니라 goto 를 쓰기에 적절하냐 적절하지 않냐를 따져야합니다. 효율성을 따져야지 좋다 안 좋다를 벌써부터 금 그어서 생각하시면 안됩니다. goto 함수를 만든 사람도 코드 해석 엿먹어라고 만들어 놓은거 아니기 때문이죠. 당연히 다 이유가 있습니다.
goto문 정말 오랫만에 보네요.

현직 프로그래머로 VC++ 쪽으로 8년째 작업 하고 있는데
회사후배나 학교 후배들에게 늘 하는 말이 코딩 습관을 잘가져라고 충고 합니다.

지금은 프로그래밍 하는게 눈에도 잘 안들어오고 실수도 많을꺼지만 나중에 익숙해 지면 머리속에서 생각한 알고리즘이나 순서도로 그냥 코딩하게 됩니다.

문제는 사람의 생각은 언제나 완벽이란게 없고 논리적인 모순이 늘 발생해서 Bug를 만듭니다. 결국 만든것도 중요하지만 이런 Bug 수정에 시간이 더 많이 잡아 먹습니다.

코딩을 할때는 간략하게 순서도를 짜보거나 프로그램 구문에 최소 이상의 주석으로 설계 내용이나 함수 설명 또는 주의 사항을 넣으면서 코딩하는 습관을 두는게 좋습니다.

goto를 쓰지말라고 하는 이유는 다른 루프문인 for, while 등과 같은 경우 브레이스 안에서 모든 동작을 하는것이 코딩상 보이기 때문에 루프 오류같은 경우는 디버깅할 포인트를 확실히 집고 갈수 있습니다. 그렇지만 goto를 쓰면 전체 함수를 다 고려해서 작업해야됩니다. goto는 특성상 하나가 아니고 2개 이상을 쓰게 만들기 때문에 순환오류가 나오기 쉽고 체크하기 매우 어렵습니다.
scanf(" %c",&selec); 이런식으로 %c 앞에 스페이스바 한번 하고 해보세요 ㅇㅅㅇ;
자동으로 개행문자 무시해주는 기능입니다.
정말 감사합니다 참고하겠습니다!
친구글 비밀글 댓글 쓰기