2013-02-04 7 views
0

저는 한 번에 한 문자 씩 읽고 십진수, 8 진수 또는 16 진수인지 확인하고 출력하기 위해 10 진수로 변환하는 프로그램을 작성하고 있습니다. 그 부분이 작동, 문제는 내가 텍스트를 통해 이동 while((ch=getchar()) != EOF) 사용하고 있지만 while 루프 절대로 절대로 종료됩니다. 나는 EOF가 -1과 같다고 말했고, EOF를 사용하는 방법은 프로그램을 끝내기 위해 + z를 제어하는 ​​것이지만, 자동으로하고 싶습니다. 저는 표준 입력뿐만 아니라 .txt 텍스트와 프로그램을 종료하지 않는 두 가지 방법을 사용했습니다. 나는 누군가가 내 코드를보고 내가 잘못한 곳을 볼 수 있는지 궁금해했다. C가 EOF를 찾지 못했습니다.

int main (void) 
{ 
    int ch, chVal, decVal ; 

    ch=getchar() ; 

    while ((ch != EOF)) 
    { 
     switch (ch) 
     { 
      case ' ' : 
       /* Just read until it’s not a space */ 
       while((ch == SPACE) || (ch== EOL)) 
         ch=getchar(); 


      case '0' : 
       /* integer, octal or hex possibilities */ 
       ch=getchar() ; 

       /**** HEX ****/ 

       if ((ch=='x') || (ch=='X')) 
       { 
        /* potential hex. So far we have read in 0x. We need to see what's next. */     
        ch=getchar() ; 

        if (ch== SPACE) 
        { 
         /* all we had was 0x entered */ 
         outputIllegalToken() ; 
         break ; /* we need to end every pass through the switch with a space char (space, eoln or eof) */ 
        } 

        decVal=0 ; 
        while ((('0' <= ch) && (ch <= '9')) || (('a' <= ch) && (ch <= 'f')) || ('A' <= ch) && (ch <= 'F')) 
        { 
         chVal = DecToHex(ch) ; 
         decVal*=16 ; 
         decVal+=chVal ; 
         ch=getchar() ; 
        } 

        /* ch is no longer a hex val. */ 
        if (ch == SPACE || ch == EOL || ch == EOF) 
        { 
         /* All is good. */ 
         outputHex(decVal); 
        } 
        else 
        { 
         if (ch=='l' || ch=='L') 
         { 
          ch=getchar() ; 
          if ((ch== SPACE) || (ch== EOL) || (ch==EOF)) 
          { 
           outputLongHex(decVal) ; 
          } 
          else 
          { 
           outputIllegalToken() ; 
           while (ch!= SPACE && ch!= EOL && ch!= EOF) 
           { 
             getchar(); 
           } 
          } 
         } 
         else 
         { 
          outputIllegalToken() ; 
          ch = getchar() ; 
          while ((ch!= SPACE) && (ch!= EOL) && (ch!= EOF)) 
          { 
           ch=getchar(); 
          } 
         } 
        } 
        printf("do we come here? \n"); 
        count++; 
        break; 
        /* end of the 0x scenario ch is a space char */ 
       } 

       /****** 0 *******/ 

       if (ch==' ') 
       { 
        /* just a 0 */ 
        outputDecimal(0); 
        count++; 
        break ; /* end of 0 alone scenario. ch is a space */ 
       } 

       /***** 0L ******/ 

       if (ch=='l' || ch=='L') { 
        /* if there is space after the l, it's ok. otherwise illegal. */ 
        ch=getchar() ; 
        if ((ch== SPACE) || (ch== EOL) || (ch==EOF)) 
        { 
         outputLongDecimal(0); 
        } 
        else 
        { 
         outputIllegalToken() ; 
         /* read to the next space */ 
         ch=getchar() ; 
         while ((ch!= SPACE) && (ch!= EOL) & (ch!=EOF)) 
           { 
           ch=getchar(); 
           } 
        } 
        count++; 
        break ; /* end of 0L scenario. ch is a space char. */ 
       } 

       /**** Octal ****/ 

       if (('0'<=ch)&&(ch<='7')) 
       { 
        /* potentially octal */ 
        chVal=DecToHex(ch) ; 
        decVal=chVal ; 
        ch=getchar() ; 
        while (('0'<=ch)&&(ch<='7')) 
        { 
         decVal*=8 ; 
         decVal+=DecToHex(ch) ; 
         ch=getchar() ; 
        } 
        /* no longer octal ch */ 
        if (ch== SPACE || ch== EOL || ch==EOF) 
        { 
         outputOctal(decVal) ; 

        } 
        else 
        { 
         if (ch=='l' || ch=='L') 
         { 
          ch=getchar() ; 
          if ((ch== SPACE) || (ch== EOL) || (ch==EOF)) 
          { 
           outputLongOctal(decVal) ; 
          } 
          else 
          { 
           outputIllegalToken() ; 
           while (ch!= SPACE && ch!= EOL && ch!=EOF) 
           { 
             getchar(); 
           } 
          } 
         } 
         else 
         { 
          outputIllegalToken() ; 
          ch = getchar() ; 
          while ((ch!= SPACE) && (ch!= EOL) && (ch!=EOF)) 
          { 
           ch=getchar(); 
          } 
         } 
        count++; 
        break;/* end octal scenario ch is a space character. */ 
       } 

       count++; 
       break ; 

      case '1': 
      case '2': 
      case '3': 
      case '4': 
      case '5': 
      case '6': 
      case '7': 
      case '8': 
      case '9': 
       /* potential decimal input */ 

       chVal=DecToHex(ch) ; /* convert the character to a number */ 
       decVal=chVal ;   /* keep track of the overall number */ 

       ch=getchar() ; 
       while (('0'<=ch) && (ch<='9')) 
       { 
        chVal=DecToHex(ch) ; 
        decVal*=10 ; 
        decVal+=chVal ; 
        ch=getchar() ; 
       } 

       /* integers have ended. spaces or l is acceptable. everything else is illegal */ 
       if ((ch== SPACE) || (ch== EOL) || (ch==EOF)) 
       { 
        outputDecimal(decVal) ; 
       } 
       else if ((ch=='l') || (ch=='L')) 
       { 
        /* next char needs to be space in order to be a valid long integer */ 
        ch==getchar() ; 
        if ((ch== SPACE) || (ch== EOL) || (ch==EOF)) 
        { 
         outputLongDecimal(decVal) ; 
        } 
        else 
        { 
         outputIllegalToken() ; 
         while ((ch!= SPACE) && (ch!= EOL) && (ch!=EOF)) 
         { 
          ch=getchar(); 
         } 
        } 
       } 
       count++; 
       break; 
     } 
    } 
} 

return 0; 
} 
+0

세 개의 'while'루프가 필요하다고 생각하지 않습니다. 그냥 공백에 대한 case 문에 아무 것도하지 말고 외부 while 루프가 마술을하도록하십시오. –

+1

EOF 어딘가에서 읽는 것 같아요. 그 다음에는 EOF 문자를 먹을 다른'getchar()'함수가옵니다. 프로그램을 재구성하거나 다른 getchar 호출 아래에서 EOF 검사를 추가하십시오. –

+0

로버트 당신은 아주 옳습니다. 나는 그 동안 루프를 제거했다. Burgos는 putchar()을 사용하여 루프가 바깥 쪽에서 반복되는 문자를 확인하고 줄 바꿈을 제공하는지 확인합니다. 그게 무슨 뜻인지는 모르겠지만 (ch! = '\ n') 포함 시키려면 while 문을 변경하려고했을 때 도움이되지 않았습니다. – Josephine

답변

0

(가 나는 경우 내에서 수행 한 뭔가 아닌지 그것은 긴, 난, 난 그냥 미안 모르는거야)이 :

  while((ch == SPACE) || (ch== EOL)) 
        ch=getchar(); 

하는 원인이됩니다 입력의 마지막 문자가 공백 인 경우 무한 루프. 나는 당신이 단순히 (ch == SPACE)을 의미한다고 생각하지만, 전체 진술을 단지 break;으로 대체하는 것도 효과가있다.

다른 버그가있을 수도 있습니다 ...

0

이것은 렉서입니다. 복잡한 휠을 재구성하는 대신 flex/lex을 사용하면 작성하고 유지 관리하기가 더 쉬운 프로그램이됩니다.

flex -Cf scanner.l 
gcc -O -o wordConverter scanner.c 

그것은 EOF 때까지 표준 입력과 출력에 입력을 받아 들인다 :

%{ 

%} 
%option 8bit outfile="scanner.c" 
%option nounput nomain noyywrap 
%option warn 

%% 

0x[0-9]+ { fprinf(yyout, "%d", yytext); /* hex conversion */ } 
0[0-9]+ { fprintf(yyout, "%d", yytext); /* octal conversion */ } 
.|\n { ECHO; /* print everything else out unmodified */ } 

%% 
int main(int argc, char **argv); 

int main (argc,argv) 
int argc; 
char **argv; 
{ 
yylex(); 
return 0; 
} 

그냥 컴파일 : 이것은 플렉스, 진수의 제로로 시작하는 진수에 대한 변환, 다른 모든 것들의 통과입니다.

+2

휠을 다시 만들기위한 코드를 작성하면 영혼에 좋으며 학습에 도움이됩니다. –

+1

@RobertHarvey 그렇다면 왜 그녀는 컴파일러 작성을 시작하지 않습니까? :) 상태 머신의 세부 사항은 디버그하기가 악명 높고 flex는 더 나은 일을합니다. 따라서이 프로그램을 빌드하는 이유가 구체적으로 상태 시스템을 작성하는 것이 아니라면 그렇게 할 이유가 없습니다. –

관련 문제