Thursday, November 12, 2015

Limbajul C. O situatie netriviala intr-o problema triviala de calculare a sumei si valorii medii a n numere

Enuntul urmator nu comporta surprize decat la final. Desigur, exista si alte variante de a asigura un input corect de tip double sau macar numeric insa, intrucat 'batrana' functie scanf are, intre altele, si proprietatea ca returneaza numarul campurilor corect citite, a fost preferata solutia de mai jos.

De reamintit ca scanf ignora caracterele white-space (tab, newline, space) si se alimenteaza din buffer (este din categoria "buffered input") la apasarea tastei Enter.

Enuntul original, din cursul predat la Cork University College (Irlanda):


4. Write a program that allows the user to read a user specified number of double precision floating point numbers from the keyboard. Your program should calculate the sum and the average of the numbers input.Try and ensure that any erroneous input is refused by your program, e.g. inadvertently entering a non-numeric character etc.

Codul, testat pentru input gresit, fie la specificarea numarului de argumente de tip double, fie la furnizarea valorilor de tip double:

#include <stdio.h>

double SumN(int n)
{
       double sum = 0.0, nr;
       int i, check;
       for(i = 1; i <= n; i++)
       {
             printf("Nr %d: ", i);
             check = scanf("%lf", &nr);
             _flushall(); // trap1
             if(1 != check)
             {
                  printf("\nErroneus input!\n");
                  i--;
                  continue;
             }
             sum += nr;
       }
       return sum;
}

int main()
{
    int n;
    double result;
    printf("\nHow many numbers do you want to sum?");
    scanf("%d", &n);
     _flushall();// trap2
    result = SumN(n);
    printf("The sum of the %d numbers is %.2lf.", n, result);
    printf("\nThe average value of the %d numbers is %.2lf.", n, result/n);
    return 0;
}


Ce se intampla la comentarea liniei marcata drept "trap1"? 

.....
printf("Nr %d: ", i);
check = scanf("%lf", &nr);
 //_flushall();
 if(1 != check)
{
     printf("\nErroneus input!\n");
     i--;
     continue;
}
sum += nr;
..........

Inlaturarea apelului functiei _flushall(), pentru golirea buffer-ului, duce programul intr-o bucla infinita la introducerea unei valori non-numerice, de pilda, o litera oarecare (caz in care variabila check ia valoarea non-1, deci se blocul conditonat de if se executa!)  
 

                                                                           
Ce se intampla la comentarea liniei "trap2"?

La un input gresit, de pilda doua valori numerice separate de spatiu, prima valoare va conta pentru numarul de iteratii (numarul de reali sumati), spatiul va fi ignorat iar a doua valoare, cea de dupa spatiu, va deveni primul termen al sumei! 


No comments:

Post a Comment