Δημοσιεύτηκε: 06 Ιούλ 2011, 17:26
από migf1
Διάβασμα ενός string και μετατροπή του σε πραγματικό αριθμό (περισσότερες πληροφορίες στα σχόλια του κώδικα :) )

Κώδικας: Επιλογή όλων
/* -----------------------------------------------------------------------------------
* Από: migf1
*
* Διάβασμα ενός string από τον χρήστη και μετατροπή του σε πραγματικό αριθμό.
*
* Το πρόγραμμα παρουσιάζει τον πλέον συμβατό και ασφαλή τρόπο να διαβάζει
* κανείς μεταβλητές οποιουδήποτε τύπου στη C, χωρίς να εξαρτάται από εν δυνάμει
* προβληματικές συναρτήσεις, όπως είναι η στάνταρ scanf().
*
* Στην προκειμένη περίπτωση το string μετατρέπεται σε double, αλλά μπορεί εξίσου
* εύκολα να μετατραπεί σε οποινδήποτε άλλον τύπο, με χρήση της στάνταρ βιβλιοθήκης
* stdlib ( #include <stdlib.h> ).
*
* Η προτεινόμενη συνάρτηση είναι η strtod() η οποία δίνει πολλές δυνατότητας ελέγχου
* αποτυχίας της μετατροπής, με χρήση της καθολικής μεταβλητής errno (#include <errno.h)
* αλλά και του δείκτη: char *dummy στο 2ο όρισμά της. Εδώ παρουσιάζω μονάχα μερικές
* από αυτές τις δυνατότητες (για περισσότερες πληροφορίες, διαβάστε την τεκμηρίωση
* της συνάρτησης, στο manual της).
*
* Ως ευκολότερη λύση για την μετατροπή, αλλά χωρίς δυνατότητα ελέγχου ενδεχόμενης
* αποτυχίας, παρουσιάζω και την συνάρτηση: atof() ( επίσης στη βιβλιοθήκη: stdlib) ).
*
* -----------------------------------------------------------------------------------
*/

#include <stdio.h>
#include <errno.h> // για έλεγχο του errno
#include <stdlib.h> // για τις atof(), strtod() και exit()

#define MAX_LINE 255+1 // μέγιστο μήκος της γραμμής εισόδου

// -----------------------------------------------------------------------------------
// Ανάγνωση του string s από την κύρια είσοδο μέχρι να πατηθεί ENTER ή να συμπληρωθούν
// maxlen-1 χαρακτήρες. Επιστρέφει το αναγνωσμένο s με μηδενισμένο τον τελικό του
// χαρακτήρα (αντικαθιστώντας το ENTER, αν ήταν αυτό ο τελικός χαρακτήρας). Σε
// περίπτωση σφάλματος επιστρέφει NULL.
// ΣΗΜΑΝΤΙΚΟ:
// το s πρέπει να είναι ήδη δημιουργημένο και να έχει χώρο για τουλάχιστον maxlen
// χαρακτήρες!
//
char *s_get(char s[], int maxlen)
{
register int i;

for (i=0; (s[i]=getchar()) != '\n' && i < maxlen-1; i++)
; // for-loop με κενό σώμα
s[i] = '\0'; // μηδενισμός του τελικού χαρακτήρα

return s;
}

// -----------------------------------------------------------------------------------
int main( void )
{
extern int errno; // defined in <errno.h>
char line[MAX_LINE]; // η γραμμή ειδόδου (string)
char *dummy; // για την strtod()
double num = 0.0; // το αποτέλεσμα της μετατροπής

printf("Enter any real number: ");
s_get( line, MAX_LINE);
printf("You entered the string: %s\n", line);

// μετατροπή με την atof()
num = atof( line );
printf("\nConverted to double with atof() it gives: %g\n", num);

// μετατροπή με την strtod()
errno = 0;
num = strtod( line, &dummy );
// έλεγχος αποτυχίας
printf("\nConverted to double with strtod() it gives: %g\n", num);
if (errno == ERANGE)
puts("\t*** error: number too big or too small");
if ( *dummy != '\0')
printf("\t*** info: \"%s\" was invalid so it was ignored\n", dummy);

exit( EXIT_SUCCESS );
}