2016-10-30 6 views
-1

私は、ユーザーがユニオンの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'は1文字をチェックします。したがって、コードは 'duedate'を文字列として扱う必要があります。次に、 'for'ループを使用して、文字列の各文字が数字であることを確認できます。 – user3386109

+1

'YYYYMMDD'の8桁のシーケンスを入力する場合は、文字列を入力する方が良いでしょう。文字列は8文字で、数字ではなく文字を処理してください。とにかく、その日付値で 'int'を持つことは、ライブラリの日付関数にとってあまり有用ではありません。 –

答えて

0

コメント欄に既に記載されているとおり、isdigit()は1文字のみです。また、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); 
} 
関連する問題