2016-10-30 2 views
-1

사용자가 공용체의 한 섹션에 입력 한 내용이 실제로 정수인지 확인하려고합니다. 나는 isdigit 함수 (아래 참조)를 사용하려고 시도했지만 성공하지 못하고있다. 내가해야 할 일은 사용자가 날짜에 대해서만 숫자를 입력하는지 확인하는 것입니다.하지만 많은 문제가 있습니다.C에서 공용체의 정수 입력 확인

내 코드 :

#define STRSIZE 30 
#define PROFSIZE 30 
#define NBRASSI 2 
#define TRUE 1 
#define FALSE 0 


struct assignment 
{ 
    char name[STRSIZE]; 
    char prof[PROFSIZE]; 
    int duedate; 
    float value; 

}; 

. . .

struct assignment populate_structure(struct assignment assi[], int assi_nbr) 
{ 
    int count; 
    int date_check = FALSE; 

for (count = 0; count < assi_nbr; count++) 
{ 
    flushall(); 
    printf("Enter Assignment #%d name (max %d chars):\n", count + 1, 
      STRSIZE); 
    gets(assi[count].name); 

    while (date_check == FALSE) 
    { 
     printf("Enter due date for Assignment #%d (YYYYMMDD):\n", 
      count + 1); 
     scanf("%d", &assi[count].duedate); 
     if (isdigit(assi[count].duedate)) 
     { 
      date_check = TRUE; 
     } 
     else 
     { 
      printf("Invalid"); 
      date_check = FALSE; 
     } 
    } 

    printf("Enter %% of final grade for Assignment #%d:\n", count + 1); 
    scanf("%f", &assi[count].value); 
    flushall(); 
    printf("Enter Professor's name for Assignment #%d (max %d chars):\n", 
     count + 1, PROFSIZE); 
    gets(assi[count].prof); 
    printf("\n\n"); 
} 
return assi[count]; 

은}

그것은 나에게 Visual Studio에서 오류를 제공하지 않습니다,하지만 난이 프로그램을 실행할 때 나는 어떤 값이 아씨 []에 입력 될 때마다 중단의 오류가 발생합니다. 내가 제거하면

을 DUEDATE if (isdigit (assi [count] .duedate)), 프로그램은 잘 동작합니다 (duedate에 정수만 입력하면). 어떤 도움이라도 대단히 감사합니다.

+3

어느 합집합입니까? 코드에는 아무 것도 없습니다. 그러나 당신의'scanf' : 반환 값을 테스트하면 확실해질 수 있습니다. '1'이어야합니다. –

+0

'isdigit'는 단일 문자를 검사합니다. 따라서 코드는 'duedate'를 문자열로 사용해야합니다. 그런 다음'for' 루프를 사용하여 문자열의 각 문자가 숫자인지 확인할 수 있습니다. – user3386109

+1

'YYYYMMDD'에 8 자리 시퀀스를 입력하는 경우 문자열을 더 잘 입력하고 길이가 8 자인지 확인한 다음 해당 문자를 처리합니다. 문자가 아닌 숫자를 처리하십시오. 그 날짜 값으로'int'를 갖는 것은 라이브러리 날짜 함수에별로 유용하지 않습니다. –

답변

0

코멘트 작성자는 이미 언급 했으므로 : isdigit()은 (는) 단일 문자로만 제공됩니다. 또한 : scanf()을 사용하는 방법은 결과가 이미 숫자임을 보장합니다.

하지만 문자열을 읽으면 테스트하기가 더 쉽습니다. 예 :

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

int main(void) 
{ 
    int c; 
    int position = 0; 
    int res; 
    char date[9] = {'\0'}; 
    char input[20] = {'\0'}; 

    puts("try if date is in the format \"YYYYMMDD\""); 
    res = scanf("%19s",input); 
    if(res != 1){ 
    fprintf(stderr,"input was a mess, aborting\n"); 
    goto __FAILURE; 
    } 
    c = input[position]; 
    while(c != '\0'){ 
    switch(position){ 
     case 0: 
      if(c == '2' || c == '1'){ 
      date[position] = (char) c; 
      } else { 
      goto __FAILURE; 
      } 
      break; 
     case 1: 
      if(c == '9' || c == '0'){ 
      // check valid digit by looking back here 
      // (not implemented) 
      date[position] = (char) c; 
      } else { 
      goto __FAILURE; 
      } 
      break; 
     case 2: 
      if(isdigit(c)){ 
      date[position] = (char) c; 
      } else { 
      goto __FAILURE; 
      } 
      break; 
     case 3: 
      if(isdigit(c)){ 
      date[position] = (char) c; 
      } else { 
      goto __FAILURE; 
      } 
      break; 
     case 4: // month 
      if(c == '0' || c == '1'){ 
      date[position] = (char) c; 
      } else { 
      goto __FAILURE; 
      } 
      break; 
     case 5: // month 
      if(isdigit(c)){ 
      // check valid digit by looking back here 
      // (not implemented) 
      date[position] = (char) c; 
      } else { 
      goto __FAILURE; 
      } 
      break; 
     case 6: // day 
      if(c == '0' || c == '1' || c == '2' || c == '3'){ 
      date[position] = (char) c; 
      } else { 
      goto __FAILURE; 
      } 
      break; 
     case 7: // day 
      if(isdigit(c)){ 
      // check valid digit by looking back here 
      // (not implemented) 
      date[position] = (char) c; 
      } else { 
      goto __FAILURE; 
      } 
      break; 
     default: 
      break; 
    } 
    c = input[++position]; 
    } 

    printf("Date was correct and is %s\n",date); 
    exit(EXIT_SUCCESS); 
__FAILURE: 
    printf("Date was wrong at position %d with character %c or just too short/long\n",position,c); 
    exit(EXIT_FAILURE); 
} 

날짜를 입력하고 (올바른 날짜 범위에 있는지 확인하십시오) 또한 문자열을 다른 문자열에 넣는 대신 개별 연도/월/일 섹션으로 나누어서 atoi을 통해 숫자로 변환 할 수 있습니다 (atoi을 사용할 수 있습니다). 또는 이미 유효한 숫자가 있어야하므로 수동으로 변환하십시오 여분의 변수 및 기능없이 스위치 내부. 산술적으로 범위를 검사하는 것은 문자열/문자를 비교하는 것보다 간단합니다.

0

여기 내 제안입니다. 더 나은 오류 처리기를 선호하지만 유효하지 않은 항목은 exit(1)입니다. 데이터는 문자열로 입력 된 다음 추출되고 유효성이 검사됩니다.

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

typedef struct { 
    int year; 
    int month; 
    int day; 
} mydate_t; 

int main(void){ 
    int i; 
    mydate_t dat = {0}; 
    int dayspermon[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 
    char str[12]; 
    printf("Enter a date (YYYYMMDD): "); 
    fflush(stdout); 
    if(fgets(str, sizeof str, stdin) == NULL) { 
     exit(1); 
    } 
    for(i=0; i<8; i++) { 
     if(!isdigit(str[i])) { 
      exit(1);     // also fails when the string is too short 
     } 
    } 

    // extract 
    for(i=0; i<4; i++) { 
     dat.year = dat.year * 10 + str[i] - '0'; 
    } 
    for(i=4; i<6; i++) { 
     dat.month = dat.month * 10 + str[i] - '0'; 
    } 
    for(i=6; i<8; i++) { 
     dat.day = dat.day * 10 + str[i] - '0'; 
    } 

    // validate 
    if(dat.year < 2000 || dat.year > 3000) // arbitrary range 
     exit(1); 
    if(dat.year % 4 == 0 && (dat.year % 100 != 0 || dat.year % 400 == 0)) { 
     dayspermon[1]++;      // leap year adjustment 
    } 
    if(dat.month < 1 || dat.month > 12) 
     exit(1); 
    if(dat.day < 1 || dat.day > dayspermon[dat.month - 1]) 
     exit(1); 

    printf("Date: %04d %02d %02d\n", dat.year, dat.month, dat.day); 
}