2011-03-29 3 views
1

그래서 C 프로그래밍 언어 책을 통해 작업하고 있습니다. 그리고 계산기 질문을 통해 일하고 있습니다. 음수에 대한 지원을 추가하도록 요청했습니다. 나는 그랬지만 나는 설명 할 수없는 이상한 행동을 발견했다.getch()로 음수 읽기

int getop(char s[]) 
{ 
    int i = 0, c, next; 
    /* Skip whitespace */ 
    while((s[0] = c = getch()) == ' ' || c == '\t') 
     ; 
    s[1] = '\0';  
    /* Not a number but may contain a unary minus. */ 
    if(!isdigit(c) && c != '.' && c != '-') 
     return c; 
    if(c == '-') 
    { 
     next = getch(); 
     if(!isdigit(next) && next != '.') 
      return c; 
     c = next; 
    } 
    else 
     c = getch();  

    while(isdigit(s[++i] = c)) //HERE 
      c = getch(); 
    if(c == '.')      /* Collect fraction part. */ 
     while(isdigit(s[++i] = c = getch())) 
         ; 
    s[i] = '\0'; 
    if(c != EOF) 
     ungetch(c); 
    return NUMBER; 
} 

양수에 대한 작품과 음수

int getop(char s[]) 
{ 
    ... 

    while(isdigit(s[++i] = c = getch())) //HERE 
      ; 
    if(c == '.')      /* Collect fraction part. */ 
     while(isdigit(s[++i] = c = getch())) 
         ; 
    s[i] = '\0'; 
    if(c != EOF) 
     ungetch(c); 
    return NUMBER; 
} 

긍정적 인 숫자 만 작동합니다.

왜 !?

getch()

char buf[BUFSIZE]; /* buffer 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(); 
} 

감사합니다.

+0

나는 그것을 할 수있을 때 대답을 받아 들인다. – Enders

+0

두 번째 버전이 어떤 종류의 숫자에도 작동하지 않습니다. 첫 번째 숫자를's'에 저장하지 못합니다. –

+0

getch는 필요한 경우 푸시 백의 BUFSIZE 바이트를 제공합니다. 왜 getchar()과 ungetc (c, stdin)를 사용하지 않는가? 그리고 아래에서 언급했듯이 비 ASCII 문자를 읽으면 isdigit (s [...]) 결과가 정의되지 않은 동작을 낳습니다. GNU libc는 이것을 막고 정의되지 않은 접근을하지 않을 것이지만, 다른 어떤 C 라이브러리는 그렇게 할 것입니다. isdigit (s [i])가 아니라 isdigit (c)를 호출 할 수 있도록 코드를 작성하는 것이 가장 좋지만 후자를해야하는 경우 unsigned char로 변환해야합니다. –

답변

1
while(isdigit(s[++i] = c)) 
    c = getch(); 

while(isdigit(s[++i] = c = getch())) 
    ; 

는 다른 행동이있다. 후자는 루프에 들어가기 전에 한 번 읽습니다. 그리고 읽은 값이 숫자인지 확인합니다. 전자는 이전에 읽은 값이 숫자인지 확인합니다.

+0

이 코드는 'signed char'보다 큰 값을 가진 문자를 읽으면 정의되지 않은 동작을합니다. 'char ...'('s [...]'와 같은) 타입의 값은'is ...'또는'to ...'로 전달하기 전에'(unsigned char)'로 형변환되어야합니다. –