تحديد ما إذا كانت سلسلة هو عدد صحيح او عدد عشري في ANSI C

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

  •  09-06-2019
  •  | 
  •  

سؤال

فقط باستخدام ANSI C, ما هي أفضل طريقة عادلة اليقين ، تحديد ما إذا كان ج النمط string هو إما صحيح أو عدد حقيقي (أنا.هـ تطفو/مزدوجة)?

هل كانت مفيدة؟

المحلول

لا تستخدم atoi و atof مثل هذه الدالات بإرجاع 0 على الفشل.آخر مرة راجعت 0 صحيحة integer و تعويم, ولذلك لا تستخدم لتحديد نوع.

استخدام strto{l,ul,ull,ll,d} وظائف هذه المجموعة errno على الفشل ، و أيضا التقرير حيث يتم تحويل بيانات العضوية.

strtoul: http://www.opengroup.org/onlinepubs/007908799/xsh/strtoul.html

يفترض هذا المثال أن السلسلة يحتوي على قيمة واحدة ترغب في تحويله.

#include <errno.h>

char* to_convert = "some string";
char* p = to_convert;
errno = 0;
unsigned long val = strtoul(to_convert, &p, 10);
if (errno != 0)
    // conversion failed (EINVAL, ERANGE)
if (to_convert == p)
    // conversion failed (no characters consumed)
if (*p != 0)
    // conversion failed (trailing data)

بفضل جوناثان Leffler بالنسبة مشيرا إلى أن نسيت أن مجموعة errno 0 أولا.

نصائح أخرى

باستخدام sscanf, يمكنك أن تكون معينة إذا كانت السلسلة هو تعويم أو الباحث أو أيا كان دون الاضطرار إلى حالة خاصة 0 ، كما هو الحال مع atoi و atof الحل.

هنا بعض التعليمة البرمجية الموجودة في المثال:

int i;
float f;
if(sscanf(str, "%d", &i) != 0) //It's an int.
  ...
if(sscanf(str "%f", &f) != 0)  //It's a float.
  ...

atoi و atof سيتم تحويل أو إعادة 0 إذا كان لا يمكن.

أنا أتفق مع Patrick_O أن strto{l,ul,ull,ll,d} المهام هي أفضل طريقة للذهاب.وهناك زوجين من النقاط إلى ساعة.

  1. مجموعة errno إلى الصفر قبل استدعاء وظائف ؛ لا وظيفة يفعل ذلك بالنسبة لك.
  2. فتح صفحة المجموعة مرتبطة (والتي ذهبت قبل أن يلاحظ أن باتريك قد يرتبط ذلك أيضا) يشير إلى أن errno قد لا يتم تعيين.ومن المقرر أن ERANGE إذا كانت القيمة خارج النطاق ؛ ذلك قد يتم تعيين (ولكن على قدم المساواة ، قد لا يتم تعيين) إلى EINVAL إذا كان حجة غير صالح.

اعتمادا على المهمة في متناول اليد ، أنا في بعض الأحيان ترتيب لتخطي زائدة المساحة البيضاء من نهاية تحويل المؤشر عاد ثم يشكو (رفض) إذا كان آخر حرف هو إنهاء null '\0'.أو يمكن أن تكون قذرة وترك القمامة تظهر في النهاية, أو أنا لا يمكن أن يقبل اختياري مضاعفات مثل 'K', 'M', 'ز', 'ر' ل كيلوبايت, بايت, جيجا, تيرابايت, ...أو أي متطلبات أخرى بناء على السياق.

أنا افترض أنك يمكن أن الخطوة من خلال سلسلة والتحقق ما إذا كان هناك أي . الشخصيات في ذلك.هذا فقط أول شيء تذكرته على الرغم من ذلك أنا متأكد من أن هناك البعض (أفضل) طرق لتكون أكثر معينة.

استخدام strtol/strtoll (لا atoi) للتحقق من الاعداد الصحيحه.استخدام strtof/strtod (لا atof) للتحقق الزوجي.

atoi و atof تحويل الجزء الأول من السلسلة, ولكن لا أقول لكم ما إذا كان أو لم تكن تستخدم جميع السلسلة.strtol/strtod أقول لك إذا كان الزائد غير المرغوب فيه بعد الشخصيات تحويلها.

إذن في كلتا الحالتين ، تذكر أن تمر في غير فارغة ذيل المعلمة ، والتحقق من أن يشير إلى نهاية السلسلة (وهذا هو ، **الذيل == 0).أيضا التحقق من قيمة الإرجاع من أجل تجاوز الحد الأدنى و تجاوز (انظر صفحات الرجل أو ANSI القياسية للحصول على التفاصيل).

نلاحظ أيضا أن strod/strtol تخطي الأولي بيضاء, حتى إذا كنت تريد لعلاج سلاسل الأولية بيضاء مثل سوء تنسيق ، تحتاج أيضا إلى التحقق من الحرف الأول.

أنها حقا يتوقف على لماذا كنت طالبا في المقام الأول.

إذا كنت ترغب فقط في تحليل عدد و لا أعرف إذا كان هو تعويم أو عدد صحيح ، ثم تحليل تعويم ، فإنه سيتم بشكل صحيح تحليل عدد صحيح كذلك.

إذا كنت فعلا تريد أن تعرف نوع ربما من أجل الفرز ، ثم عليك أن تنظر حقا اختبار أنواع بالترتيب الذي كنت تعتبر الأكثر أهمية.مثل محاولة تحليل عدد صحيح إذا كنت لا تستطيع ، ثم محاولة تحليل تعويم.(العكس سوف تنتج أكثر قليلا تعوم...)

atoi و atof سيتم تحويل عدد حتى لو كانت هناك زائدة غير العددية الشخصيات.ومع ذلك ، إذا كنت تستخدم strtol و strtod وسوف ليس فقط تخطي الرائدة في المساحة البيضاء اختياري علامة ، ولكن أترككم مع مؤشر إلى أول حرف في عدد.ثم يمكنك التحقق من أن بقية بيضاء.

حسنا, إذا كنت لا تشعر مثل استخدام وظيفة جديدة مثل strtoul يمكنك فقط إضافة آخر strcmp البيان أن نرى إذا كانت السلسلة هو 0.

أي

if(atof(token) != NULL || strcmp(token, "0") == 0)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top