سؤال

لدي قطعة من التعليمات البرمجية التي تقدم سؤالا مثيرا للاهتمام (في رأيي).

/*power.c raises numbers to integer powers*/
#include <stdio.h>

double power(double n, int p);

int main(void)
{
    double x, xpow; /*x is the orginal number and xpow is the result*/
    int exp;/*exp is the exponent that x is being raised to */

    printf("Enter a number and the positive integer power to which\n the first number will be raised.\n enter q to quit\n");

    while(scanf("%lf %d", &x, &exp) ==2)
    {
        xpow = power(x, exp);
        printf("%.3g to the power %d is %.5g\n", x, exp, xpow);
        printf("enter the next pair of numbers or q to quit.\n");
    }

    printf("Hope you enjoyed your power trip -- bye!\n");
    return 0;
}

double power(double n, int p)
{
    double pow = 1;
    int i;

    for(i = 1; i <= p; i++)
    {
        pow *= n;
    }
    return pow;
}

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

[mike@mike ~/code/powerCode]$ ./power
Enter a number and the positive integer power to which
 the first number will be raised.
 enter q to quit
1 2.3
1 to the power 2 is 1
enter the next pair of numbers or q to quit.
2 3.4
0.3 to the power 2 is 0.09
enter the next pair of numbers or q to quit.

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

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

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

المحلول

عند قراءة أول "2.3" أول قراءة حتى "." يدرك أنه لم يعد عددا صحيحا ويتوقف. لذلك يتم ترك ".3" في المخزن المؤقت، ثم اكتب "2 3.4" لذلك ".3 N2 3.4" في المخزن المؤقت. عندما يحدد SCANF أنه يحصل ".3" و "2" تماما مثل مثالك.

نصائح أخرى

هذا لأنه عند استخدام Scanf لقراءة "2.3"، يتوقف المسح الضوئي، ولكن لا يستهلك "." في 3". وبالتالي، عند إجراء مكالمة التالية إلى Scanf، يبدأ بالقراءة في ".3".

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

أجاب آخرون على سؤالك المحدد ولكن أود تقديم نصيحة واحدة. أبدا استعمال scanf() أو fscanf(). وبعد أي وقت مضى. عنجد.

الفشل خلال أ [f]scanf() يترك التشغيل دائما مؤشر الملف الخاص بك في موقع غير محدد. نظرا لأن معظم المدخلات من المستخدمين يعتمد بشكل عام على خطوط (باستثناء واجهة المستخدم العالمية)، فإن خيار استخدام fgets() و sscanf() هو دائما أفضل، في رأيي.

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

بمعنى آخر، إذا كان sscanf() فشل، لا يزال لديك الخط المتاح لأغراض أخرى (رخص من سلسلة تنسيق مختلفة أو حتى ببساطة إخراجه بخطأ) دون الحاجة إلى المرور stdio الجمباز للعودة إلى بداية الخط في الملف (من الصعب مع ملف، مستحيل مع Stdin من محطة).

في C، SCANF () غير مجدية بشكل أساسي لإدخال العالم الحقيقي من المستخدمين البشري - من المقصود في قراءة نص تنسيق ثابت من ملفات البيانات. إذا كنت تستخدم C ++، فيجب أن تستخدم إدخال IOSTREAM، وفي كلتا الحالتين، يجب عليك حقا كتابة إجراءات تحليلك الخاصة لمتطلبات الإدخال المحددة الخاصة بك.

سأقرأ الخطوط داخل واستخدام SSCANF لتحليل كل سطر. وأنا أتفق مع الآخرين، هناك أساليب أفضل من SSCANF على الرغم من ذلك.

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