كيفية التأكد من الإدخال مزدوج في لغة البرمجة C

StackOverflow https://stackoverflow.com/questions/1681873

  •  16-09-2019
  •  | 
  •  

سؤال

كيف أتأكد من أن لدي مضاعفة وليس شيئا آخر؟

int main() {
    int flagOk = 0;
    double number;
    while(!flagOk) {
        printf("Put in a double");
        scanf("%lf", &number);
        if(number == "%lf"); //this want make sure
        flagOk = 1;
    }
}
هل كانت مفيدة؟

المحلول

ربما تريد شظية رمز أكثر مثل هذا:

double number;
do {
    printf("Enter a double: ");
    scanf("%*c"); // burn stdin so as not to buffer up responses
} while (1 != scanf("%lf", &number));

ومع ذلك، كما أشار جوناثان، قد يكون بعض التحليلات الأفضل في الخط أفضل. المسح مباشرة من stdin هذه الطريقة ليست بديهية للمستخدم.

نصائح أخرى

تحقق من قيمة الإرجاع من scanf(); ؛ يخبرك بعدد التحويلات الناجحة.

في السياق، إذا فشل التحويل، تحصل على 0؛ إذا نجحت، تحصل على 1.

يجب التفكير في استرداد الخطأ. عادة ما أجد أنه من الأسهل قراءة خط البيانات باستخدام fgets()لا يحصل أبدا ()!) ثم أعالجها sscanf(). وبعد من السهل تجاهل البيانات الخاطئة إذا فشل التحويل.

إذا كنت ترغب في التأكد من أن القيمة المتوقعة من المستخدم تتزامن مع القيمة التي يتم إرجاعها عن طريق تمرير السلسلة إلى atof (str) - بما في ذلك تدوين الأسهم - ثم يعمل الكود التالي.

يمكنك الحصول على المدخلات باستخدام fgets (شارع، الحجم، ستودين), ، وليس لديك حتى إزالة الخط الجديد زائدة قبل تمرير السلسلة إلى المحلل المحلل.

أيضا، إذا كان هناك خطأ تحليل، فإن الوظيفة تقارير موقع الحرف الموضح إلى مؤشر مرت كوسيطة إضافية.

هناك شكل طويل - أسهل القراءة، ونموذج قصير - أسهل في الكتابة.

وثيقةطويلة:


/*
    Copyright (C) 2010  S. Randall Sawyer

This code is in the public domain.  It is intended to be usefully illustrative.
It is not intended to be used for any particular application. If this code is
used in any application - whether open source or proprietary, then please give
credit to the author.

*/

#include  <ctype.h>

#define FAILURE (0)
#define SUCCESS (!FAILURE)

enum {
  END_EXPRESSION        = 0x00,
  ALLOW_POINT           = 0x01,
  ALLOW_NEGATIVE        = 0x02,
  REQUIRE_DIGIT         = 0x04,
  ALLOW_EXPONENT        = 0x08,
  HAVE_EXPONENT         = 0x10,
  EXPECT_EXPRESSION     = ALLOW_POINT | ALLOW_NEGATIVE | REQUIRE_DIGIT,
  EXPECT_INTEGER        = ~ALLOW_POINT,
  EXPECT_POS_EXPRESSION = ~ALLOW_NEGATIVE,
  EXPECT_POS_INTEGER    = EXPECT_INTEGER & EXPECT_POS_EXPRESSION,
  EXPECT_EXPONENT       = EXPECT_INTEGER ^ HAVE_EXPONENT,
  EXPONENT_FLAGS        = REQUIRE_DIGIT | ALLOW_EXPONENT | HAVE_EXPONENT
} DoubleParseFlag;

int double_parse_long ( const char * str, const char ** err_ptr )
{
  int ret_val, flags;
  const char * ptr;

  flags = EXPECT_EXPRESSION;
  ptr   = str;

  do  {

    if ( isdigit ( *ptr ) ) {
      ret_val = SUCCESS;
      /*  The '+' here is the key:  It toggles 'ALLOW_EXPONENT' and
          'HAVE_EXPONENT' successively  */
      flags = ( flags + ( flags & REQUIRE_DIGIT ) ) & EXPECT_POS_EXPRESSION;
    }
    else if ( (*ptr & 0x5f) == 'E' )  {
      ret_val = ( ( flags & ( EXPONENT_FLAGS ) ) == ALLOW_EXPONENT );
      flags = EXPECT_EXPONENT;
    }
    else if ( *ptr == '.' ) {
      ret_val = ( flags & ALLOW_POINT );
      flags = ( flags & EXPECT_POS_INTEGER );
    }
    else if ( *ptr == '-' ) {
      ret_val = ( flags & ALLOW_NEGATIVE );
      flags = ( flags & EXPECT_POS_EXPRESSION );
    }
    else if ( iscntrl ( *ptr ) )  {
      ret_val = !( flags & REQUIRE_DIGIT );
      flags = END_EXPRESSION;
    }
    else  {
      ret_val = FAILURE;
      flags = END_EXPRESSION;
    }

    ptr++;

  } while (ret_val && flags);

  if (err_ptr != NULL)
    *err_ptr = ptr - 1;

  return ret_val;
}

نموذج قصير:


/*
    Copyright (C) 2010  S. Randall Sawyer

This code is in the public domain.  It is intended to be usefully illustrative.
It is not intended to be used for any particular application. If this code is
used in any application - whether open source or proprietary, then please give
credit to the author.

*/

#include  <ctype.h>

int double_parse_short ( const char * str, const char ** err_ptr )
{
  int ret_val, flags;
  const char * ptr;

  flags = 0x07;
  ptr   = str;

  do  {

    ret_val = ( iscntrl ( *ptr ) ) ? !(flags & 0x04) : (
              ( *ptr == '.' ) ? flags & 0x01 : (
              ( *ptr == '-' ) ? flags & 0x02 : (
              ( (*ptr & 0x5f) == 'E' ) ? ((flags & 0x1c) == 0x08) : (
              ( isdigit ( *ptr ) ) ? 1 : 0 ) ) ) );

    flags =   ( isdigit ( *ptr ) ) ?
                (flags + (flags & 0x04)) & 0x1d : (
              ( (*ptr & 0x5f) == 'E' ) ? 0x0e : (
              ( *ptr == '-' ) ? flags & 0x1d : (
              ( *ptr == '.' ) ? flags & 0x1c : 0 ) ) );

    ptr++;

  } while (ret_val && flags);

  if (err_ptr != NULL)
    *err_ptr = ptr - 1;

  return ret_val;
}

آمل أن يساعد هذا!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top