2013-02-04 95 views
0

我正在編寫一次讀取輸入一個字符並確定它是十進制,八進制還是十六進制並將其轉換爲十進制輸出的程序。這部分工作,問題是我使用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語句中放一個do-nothing,讓外層的'while'循環發揮它的魔力。 –

+1

我猜你正在讀某個地方的EOF,然後是另一個'getchar()'函數,它將會吃掉EOF字符。要麼重新構造您的程序,要麼在其他'getchar'調用下添加EOF檢查。 –

+0

羅伯特你很對。我擺脫了那個while循環。 布爾戈斯如果我使用putchar()來查看外部while循環中的字符循環是什麼,它正在給我一個換行符。我不知道這意味着什麼,但是當我試圖改變while語句以包含(ch!='\ n')時,它也沒有幫助。 – Josephine

回答

0

此:

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

會引起如果輸入中的最後一個字符是空格,則爲無限循環。我認爲你的意思只是(ch == SPACE),但用break;替換整個聲明也可以。

可能還有其他的bug ...

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做得更好。所以,除非構建這個程序的原因是專門編寫一個狀態機,否則沒有理由這麼做。 –