2013-07-05 3 views
0

저는 독자적으로 C 프로그래밍을 연습하고있었습니다. 필자가 작성한 프로그램은 getfloat로, 문자 스트림을 float (K & R exercise 5-2)에서 변환합니다. 나는 getch와 ungetch를 사용하여 버퍼 나 입력에서 다음 문자를 가져 오는 코드 스 니펫을 사용했습니다. 내 코드의 문제점은 필자가 작성한 Visual Studio에서 계산 및 변환을 올바르게 수행 한 후에 값을 인쇄 할 수 없다는 점입니다. 나는 프로그램을 밟아서 내 함수의 변수 c가 아마도 변환의 끝에서 10 대신에 -1이된다는 것을 알았다. 내 코드는 다음과 같습니다.결과를 표시 할 수 없습니다.

#include <stdio.h> 
#include <ctype.h> 

int getch(void); 
void ungetch(int c); 
int getfloat(float *pn); 
int main(void) 
{ 
int ret; 

    float f; 
    printf("enter a float number:\n"); 
    ret=getfloat(&f); 
    if(ret>0) 
     printf("you've entered: %f",f); 

if (ret == EOF) 
{ 
     puts("Stopped by EOF."); 
} 
else 
{ 
     puts("Stopped by bad input."); 
} 

return 0; 
} 

int getfloat(float *pn) 
{ 
char c,sign,dec; 
float pow; 
while(isspace(c=getch())) 
    ; 
if(!isdigit(c)&&c!=EOF&&c!='-'&&c!='+'&&c!='.') 
{ 
    ungetch(c); 
    return 0; 
} 
sign=(c=='-')?-1:1; 
if(c=='-'||c=='+') 
     c=getch(); 
if(!isdigit(c)) 
{ 
    ungetch(c); 
    return -1; 
} 
for(*pn=0;c!=EOF && isdigit(c);c=getch()) 
    *pn=10* (*pn)+ (c-'0'); //calculate the integer part// 

if((c=getch())=='.') 
{ 
    for(*pn,dec=1;c!=EOF && isdigit(c);c=getch()) 
    { 
     *pn=10* (*pn)+ (c-'0'); //calculate the decimal part// 
     dec=dec*10; 
    } 
    *pn=*pn*sign/dec; 
} 

if((c=getch())=='e') 
{ 
     if((c=getch())=='-') 
     for(*pn,pow=0.1;c!=EOF && isdigit(c);c=getch()) 
    { 
     *pn=10* (*pn)+ (c-'0'); 
     dec=dec/10; 
    } 
    else 
    { 
     ungetch(c); 
     for(*pn,pow=1.0;c!=EOF && isdigit(c);c=getch()) 
     { 
      *pn=10* (*pn)+ (c-'0'); 
      dec=dec*10; 
     } 
    } 
*pn=*pn*sign*dec; 
} 
if(c!=EOF) 
    ungetch(c); 
return c; 
} 




#define BUFSIZE 100 

char buf[BUFSIZE];  /* bufer for ungetch */ 
int bufp = 0;   /* next free position in buf */ 

int getch(void)   /* get a (possibly pushed-back) character */ 
{ 
    return (bufp > 0) ? buf[--bufp] : getchar(); 
} 

void ungetch(int c)  /* push character back on input */ 
{ 
     if (bufp >= BUFSIZE) 
       printf("ungetch: too many characters\n"); 
     else 
       buf[bufp++] = c; 
} 
+3

코드를 더 잘 포맷하는 것이 좋습니다. K & R은 좋은 예입니다. 형식이 잘 지정된 코드는 눈이 쉬우 며 이해하기 쉽습니다. 또한 TAB을 사용하지 마십시오. 다른 TAB 너비가있는 환경에서는 레이아웃이 엉망입니다. –

답변

2

프로그램에 너무 많은 문제가 있습니다. 여기 몇 사람은 다음과 같습니다 dec가 초기화되지 않은 곳

dec=dec*10; 

은 프로그램의 일부 유효한 코드 경로가 있습니다.

char c,sign,dec; 

/* ... */ 

if(c!=EOF) 

EOF 부정적인 int 너무 cchar로서 int하지 선언되어야한다.

+0

명확히하기 위해 EOF는 -1이며 정수 여야합니다. 맞습니까? btw, 나는 내 프로그램을 검사했고 지수를 다루는 다른 코드 경로에서 dec 대신에 다른 변수 펑션을 사용하려고했다. – user2309838

+0

'EOF'는 일반적으로 -1로 정의되지만, 표준에서는 음수가 필요합니다. 일반적인 의도는 문자 값을 반환하는 함수는'unsigned char', 또는'EOF'에 맞는 것을 돌려 줄 것입니다. 즉, 257 개의 가능한 반환 값이 있으므로 변수가 'int'이어야합니다. –

+0

@ user2309838 대답에 넣은대로'EOF'는 음수'int'입니다. 그래서 값은'-1'과 다른 형태 일 수 있고 타입은'int'와 다를 수 없습니다 ('signed char'는 정수형이 아닙니다.). – ouah

0
int getfloat(float *pn){ 
    int c,sign,dec; 
    float pow, tmp; 

    while(isspace(c=getch())) 
     ; 
    if(!isdigit(c) && c!=EOF && c!='-' && c!='+'){//&&c!='.' 
     ungetch(c); 
     return 0; 
    } 
    sign=(c=='-')?-1:1; 
    if(c=='-'||c=='+') 
     c=getch(); 
    if(!isdigit(c)){ 
     ungetch(c); 
     return -1; 
    } 
    for(*pn=0;c!=EOF && isdigit(c);c=getch()) 
     *pn = 10* (*pn)+ (c-'0'); //calculate the integer part// 
    *pn *= sign; 

    if(c=='.'){ 
     c = getch(); 
     tmp=0; 
     for(dec=1;c!=EOF && isdigit(c);c=getch()){ 
      tmp=10 * tmp + (c-'0'); //calculate the decimal part// 
      dec=dec*10; 
     } 
     *pn = *pn + sign * tmp/dec; 
    } 

    if(c=='e'){ 
     c=getch(); 
     sign=(c=='-')?-1:1; 
     if(c=='-') 
      c=getch(); 
     for(tmp=0;c!=EOF && isdigit(c);c=getch()) 
      tmp=10 * tmp + (c-'0'); 
     printf("debug:%f\n", sign*tmp); 
     *pn=*pn*powf(10.0f, sign*tmp); 
    } 
    if(c!=EOF) 
     ungetch(c); 
    return c; 
} 

여전히이 문제는 어쩌면

0

for (*pn, ...) 달성하기 위해 무엇을 의미? 이것은 루프의 초기화 단계이지만 *pnpn이 가리키는 부분을 가져 와서 버립니다.

+0

맞습니다. 루프에서 * pn을 초기화하려고하지 않았습니다. 나는 그것을 그냥 지울거야. – user2309838