1

キーボードから整数を取得するために、次のコードを記述しました。有効な整数値(負または正)を指定するまで、エラーメッセージが表示されます。

1つの条件は、考えられるすべてのテストケースをチェックする必要があることです。

お気に入り:

-3.2 
5.0
984237.4329
0.343
.434
12344.
adfs34
233adds
3892710492374329
helloIamNotainteger 

このすべてのテストで失敗するはずint >=INT_MIN && int <=INT_MAX です。値に対してのみ合格します。

私の実行中のコードは:

#include<stdio.h>
#include<limits.h>

int min=INT_MIN;
int max=INT_MAX;

int main()
{
        char str[50],c; //I have taken size 50 please ignore this 
        int check;
 do
 {
        int flag=1,i=0,j=0,num=0;
        check=0;
        printf("Enter an Integer : ");
        while((c=getchar())!='\n')
                str[i++]=c;
        if(str[0] == '-')
        {
                flag = -1;
                j++;
        }
        for(;j<i;j++)
        {
                if(str[j] >= '0' && str[j] <= '9')
                        num=(str[j]-'0') + num*10;
                else
                        break;

        }
        if(j<i)
        {
          printf("Not an Integer, Please input an integer \n");
        }
        else if(num < min || num >max)
        {
          printf("Integer is out of range,Please input an integer \n");
        }
        else
        {
                num *=flag;
                printf("The given number is : %d\n",num);
                check=1;
        }
 }while(check == 0);
        return 0;

}

一例:このような値の場合。
83429439803248832409(整数ですが、範囲が原因で失敗するはずです)が、合格して他の整数値を返します。

私のコード内でこれを解決する方法、または実装するためのより良いアイデアはありますgetInt()か?

4

5 に答える 5

2

これを行う最も簡単な方法は、標準ライブラリ関数を使用することです。

#include <limits.h>
#include <stdlib.h>

int getInt (const char *s)
{
    long int n = strtol (s, NULL, 10);

    if (n < INT_MIN || n > INT_MAX)
        /* handle overflows */
    else
        return (int) n;
}

他のエラーを処理するには、いくつかの条件を使用できます。

#include <errno.h>

int getInt (const char *s, size_t size)
{
    const char *pEnd1 = s + size;
    char *pEnd2;
    long int n;

    errno = 0;

    n = strtol (s, &pEnd2, 10);

    if (n < INT_MIN || n > INT_MAX || errno != 0 || pEnd1 != pEnd2)
        /* error */
    else
        return (int) n;
} 
于 2012-11-08T11:54:09.373 に答える
0

これはKirilenkoのよくチェックするソリューションへのコメントとして適していますが、私のメモは長すぎるので、回答として投稿します。

変換関数の主な問題は、変換が期待どおりに行われたかどうかをテストすることが困難 ( strtol()) または不可能 ( ) であることです。atoi()

atoi()したがって、信頼性を高め (as として)、使いやすく(as として)しようとする場合、 Kirilenkostrtol()のようなソリューションが使用されます。

とにかく、Omkantによって提供されるアプローチは、変換で何か問題が発生した場合 (呼び出し元の観点から)、機能しないという設計ミスに悩まされています。

したがって、インターフェイスは、結果を関数値として返す他の多くのシステム関数のインターフェイスに似ている必要があります。

/* 
 * Tryies to convert the first 'size' characters of 's' to an 'int' and optionally 
 * writes it to '*result'.
 * 
 * Returns the number of characters converted or any qualified negative error code
 * on failure.
 */
int getInt(
  const char * s,  /* source string to try to be converted to an integer */
  size_z size, /* number of digits to be converted (shall not be > strlen(s)) */
  int * result /* optional reference to an int to place the conversion result in */
);

そして、注目すべき副作用として、NULL最後のパラメーターとしてのバイパスは、変換が機能するかどうかを簡単にテストでき、さらに、結果の整数に必要な桁数を受け取ることができます。


この変換関数を、その結果を関数値として返すかのように引き続き使用できるようにするには、次のマクロを使用すると便利な場合があります。

GETINT(str, size, result, rc) \
  (rc = getInt(str, size, &result), result)

使用法:

char s[] = "42";
int rc = 0;
int i = GETINT(s, 2, i, rc);
if (rc)
  /* some error */
else
  /* use i */
于 2012-11-08T13:36:12.450 に答える
0

32768 を超える値を整数 (符号なしではない) に格納しようとしています。そのため、それを行うと、ストレージ変数に存在していたガベージ値が表示されます。ご存じのとおり、c の整数にはメモリ制限があります。unsigned 型の int データ型と同様に、0 ~ 65535 の値を格納できます。したがって、それ以上の数値を格納しようとすると問題が発生します。より大きな数値を格納する必要がある場合は、long int データ型を使用してみてください。多分それは役立つかもしれません。しかし、そのデータ型には、4lakh に近い値のメモリ制限もあります。

それが役立つことを願っています。

于 2012-11-08T12:31:13.757 に答える
0

簡単な方法の 1 つは、それらを文字列として比較することです。まず、32 ビット整数は 10 桁 (および符号) を超えることはできないことに注意してください。

int32_t get_int32()
{
    char input[13];
    char check[12];
    int32_t result;

    if (scanf("%12s", input) != 1)
        /* handle error */
    /* ignore rest of number if any */
    ungetc('x', stdin);
    scanf("%*s");

    /* if length is bigger than 11, error */
    if (strlen(input) > 11)
        /* handle error */

    if (sscanf(input, "%"SCNd32, &result) != 1)
        /* handle error */
    sprintf(check, "%"PRId32, result);

    if (strcmp(input, check) != 0)
        /* handle error */

    return result;
}

strlenチェックは無視することができ、 が処理することに注意してくださいstrcmp。また、十分inputに大きい場合 (たとえば )、 64 ビットを超えることはできないことがわかっているため (少なくとも何年もの間)、代わりに安全に使用できることに注意してください。check25intint32_t

于 2012-11-08T13:44:22.473 に答える
0

ここに作業コードがあります:これを見てください、私はそれをせずにそれをしましたstrtol、そしてそれはすべての条件を満たし、int

    #include<stdio.h>
    #include<limits.h>
    #include<string.h>

    int main()
    {
            int num;
            char str[500],c;
            int check;
            char max[12];
            char min[12];
            sprintf(max,"%d",INT_MAX);
            sprintf(min,"%d",INT_MIN);
     do
     {
            int flag=1,i=0,j=0;
            num=0;
            check=0;
            printf("Enter an Integer : ");
            while((c=getchar())!='\n')
                    str[i++]=c;
            str[i]='\0';
            if(str[0] == '-')
            {
                    flag = -1;
                    j++;
            }
            for(;j<i;j++)
            {
                    if(str[j] >= '0' && str[j] <= '9')
                            check = 1;               
                else
                {
                        check = 0;
                        break;
                }

        }
        if(check == 0)
        {
                printf("Not an Integer, Please input an integer \n");
        }
        /************Start of checking integer range **************/
        else
        {
                if( (flag == -1 && (strlen(str) > strlen(min))) || 
                    (flag == 1 && (strlen(str) > strlen(max))) )
                {
                        check = 0;
                        printf("Integer is out of range, \n");
                }
                else if(flag == -1 && (strlen(str) == strlen(min)) )
                {
                        i=0;
                        while(min[i]!='\0')
                        {
                                if (str[i] > min[i])
                                {
                                        check = 0;
                                        printf("Integer is out of range \n");
                                        break;
                                }
                                i++;                        }
                        if(check == 1)
                        {
                                for(j=1;j<strlen(str);j++)
                                        num=(str[j]-'0')+num*10;
                                num *=flag;
                                printf("The given number is : %d\n",num);
                        }
                }

                else if(flag == 1 && (strlen(str) == strlen(max)) )
                {
                        i=0;
                        while(max[i]!='\0')
                        {
                                if (str[i] > max[i])
                                {
                                        check = 0;
                                        printf("Integer is out of range\n");
                                        break;
                                }
                                i++;
                        }
                        if(check == 1)
                        {
                                for(j=0;j<strlen(str);j++)
                                        num=(str[j]-'0')+num*10;
                                num *=flag;
                                printf("The given number is : %d\n",num);
                        }
                }
                else
                {
                for(j=0;j<strlen(str);j++)
                        num=(str[j]-'0')+num*10;
                num *=flag;
                printf("The given number is : %d\n",num);
                }
        }
        /************End of checking integer range ****************/
 }while(check == 0);

return 0;
于 2012-11-08T19:26:22.417 に答える