• C

Error checking with double and dividing the program into 2 modules (stdout and stdin)

Im trying to make the program exit if the user is not entering a double in startkm and endkm
Here is how the program looks like:
[code]

#include <stdio.h>
#include <stdlib.h>
#include "Car.h"

int main ( void )
{
     char line[82];
     int startkm, endkm, last , total = 0 ;
     int no_of_trips = 0;
     float avg_trip_length ;
     int i;
     int count;

     last = -1; /* date being checked when user will enter the first line */
     while ( fgets ( line, sizeof line, stdin ) != NULL )
     {
          //validate(...);
          i = 0; count = 0;
          while (line[i] != '\n' && line[i] != '\0') {
               if (line[i] == '\t') {
                    count++;
               }
               if ( i >= 79 )
               {
                    fprintf ( stderr, "\n The input exceeds 80 characters. " ) ;
                    return EXIT_FAILURE;

               } /* end if, for */
               i++;
          }
          if (count != 4) /*not 4 blank-spaces: error*/
          {
               fprintf(stderr, "\nYou did not enter 5 fields. Error.");
               return EXIT_FAILURE;
          }      

        sscanf( line, "%*[^\t]%d %d%*[^\t]%*[^\n]", &startkm, &endkm ) ;        
        total += ( endkm - startkm ) ;
 
        if ( startkm >= endkm )
        {
           fprintf(stderr, "\n Invalid. Start km must be greater than end km... " ) ;
           return EXIT_FAILURE;

        } /* end if */
     
        if ( startkm < last )
        {
           fprintf(stderr, "\nError! Start km in one record must be greater or less than end km of the previous record. " ) ;
           return EXIT_FAILURE;

        } /* end if */
        no_of_trips++ ;
        last = endkm;
   
     } /* end while */

 avg_trip_length = calc_avg( total, no_of_trips ) ;
 printf( "\n Number of trips: %d \n Total kilometres: %d \n Average trip length: %.2f\n", no_of_trips, total , avg_trip_length ) ;

 return 0 ;
                   
} /* end of main () */

float calc_avg ( int t, int n )
{
 return ( ( float ) t ) / n ;

} /* end of calc_avg () */

[/code]

Now I am not too shure how to check that start km and end km are both decimal numbers and that the program will exit if its not by showing an error..

A easier way would be using StringTok. but Ill need to remove sscanf and I dont have the strength to redo the whole program again

I want the program to read the double of startkm and endkm to read it as a string
Here is what im doing using sscanf but its not giving me the correct error:

[code]
sscanf( line, "%*[^\t a-zA-Z ]%d%*[0-9] %d%*[0-9]%*[^\t a-zA-Z]%*[^\n]", &startkm, &endkm ) ;
[/code]

Should I add an if statement to prove that if the string is not between 0-9 then exit?
thats getting really confusing..
TQ.
thiboAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

gj62Commented:
You've got a few things going on here.

First, you keep saying double (which allows decimals, e.g. 5.4356, etc).  

However, you define them as int's, and use %d (for ints), rather than %lf (doubles) in your scanf.

Lastly, I'd recommend that you read the user input into a string, then convert the string into your double (be sure you declare it as a double) using strtod().  You have more flexibility checking for errors that way...
0
thiboAuthor Commented:
Ok so I would need to do:

#include <stdio.h>
#include <stdlib.h>
#include "Car.h"

int main ( void )
{
    char line[82];
    double startkm, endkm,
    int last , total = 0 ;
    int no_of_trips = 0;
    float avg_trip_length ;
    int i;
    int count;

    last = -1; /* date being checked when user will enter the first line */
    while ( fgets ( line, sizeof line, stdin ) != NULL )
    {
         //validate(...);
         i = 0; count = 0;
         while (line[i] != '\n' && line[i] != '\0') {
              if (line[i] == '\t') {
                   count++;
              }
              if ( i >= 79 )
              {
                   fprintf ( stderr, "\n The input exceeds 80 characters. " ) ;
                   return EXIT_FAILURE;

              } /* end if, for */
              i++;
         }
         if (count != 4) /*not 4 blank-spaces: error*/
         {
              fprintf(stderr, "\nYou did not enter 5 fields. Error.");
              return EXIT_FAILURE;
         }      

       sscanf( line, "%*[^\t]%f %f%*[^\t]%*[^\n]", &startkm, &endkm ) ;        
       total += ( endkm - startkm ) ;

       if ( startkm >= endkm )
       {
          fprintf(stderr, "\n Invalid. Start km must be greater than end km... " ) ;
          return EXIT_FAILURE;

       } /* end if */
     
       if ( startkm < last )
       {
          fprintf(stderr, "\nError! Start km in one record must be greater or less than end km of the previous record. " ) ;
          return EXIT_FAILURE;

       } /* end if */
       no_of_trips++ ;
       last = endkm;
 
    } /* end while */

avg_trip_length = calc_avg( total, no_of_trips ) ;
printf( "\n Number of trips: %d \n Total kilometres: %d \n Average trip length: %.2f\n", no_of_trips, total , avg_trip_length ) ;

return 0 ;
                 
} /* end of main () */

float calc_avg ( int t, int n )
{
return ( ( float ) t ) / n ;

} /* end of calc_avg () */

[/code]

Do i need to increment new pointers for converting string into double like for ex.:

char *string, *compString;
.
.
.
string = ?
x = strtod( string, &compString);

TQ.
0
gj62Commented:
I gotta run - on the surface, this looks closer.  However, last and total also need to be doubles to be correct.

You haven't really used strings - you are still using scanf with format specifiers for your numbers.  You can do it this way, but you have less flexibility when checking for errors...

Anyhow, since you are not reading from strings (you said you don't want to use strtok, you can just ignore my recommendation to use strtod.


0
Creating Active Directory Users from a Text File

If your organization has a need to mass-create AD user accounts, watch this video to see how its done without the need for scripting or other unnecessary complexities.

thiboAuthor Commented:
k ill try it again to make it work
thx for ure help
:)
0
thiboAuthor Commented:
I tried making all the variables double but it is not compiling properly..
0
adg080898Commented:
I fixed a few syntax errors and added one validity check. You were mixing floats and doubles and ints. When scanning from scanf you have to be careful about floats and doubles. Use %f for floats and %lf (pronounced ell-eff) for doubles.

Another problem was that there was no prototype for calc_avg so the compiler assumed that it returned int. It doesn't return int and the compiler later notices that it does not return int, giving error messages. I added a prototype to allow the compiler to see that it returns double.

[code]

#include <stdio.h>
#include <stdlib.h>
#include "Car.h"

// Prototype for forward reference
double calc_avg ( double t, double n );

int main()
{
   char line[82];
   float startkm, endkm;
   int no_of_trips = 0;
   double total = 0 , avg_trip_length, last ;
   int i;
   int count;

   last = -1; /* date being checked when user will enter the first line */
   while ( fgets ( line, sizeof line, stdin ) != NULL )
   {
        //validate(...);
        i = 0; count = 0;
        while (line[i] != '\n' && line[i] != '\0') {
             if (line[i] == '\t') {
                  count++;
             }
             if ( i >= 79 )
             {
                  fprintf ( stderr, "\n The input exceeds 80 characters. " ) ;
                  return EXIT_FAILURE;

             } /* end if, for */
             i++;
        }
        if (count != 4) /*not 4 blank-spaces: error*/
        {
             fprintf(stderr, "\nYou did not enter 5 fields. Error.");
             return EXIT_FAILURE;
        }      

      i = sscanf( line, "%*[^\t]%f %f%*[^\t]%*[^\n]", &startkm, &endkm ) ;        
       if (i == 0) {
            fprintf(stderr, "\nIgnored line" ) ;
            continue;
       }
       if (i == EOF)
            break;

      total += ( endkm - startkm ) ;

      if ( startkm >= endkm )
      {
         fprintf(stderr, "\n Invalid. Start km must be greater than end km... " ) ;
         return EXIT_FAILURE;

      } /* end if */
   
      if ( startkm < last )
      {
         fprintf(stderr, "\nError! Start km in one record must be greater or less than end km of the previous record. " ) ;
         return EXIT_FAILURE;

      } /* end if */
      no_of_trips++ ;
      last = endkm;
 
   } /* end while */

avg_trip_length = calc_avg( total, no_of_trips ) ;
printf( "\n Number of trips: %d \n Total kilometres: %lf \n Average trip length: %.2lf\n", no_of_trips, total , avg_trip_length ) ;

return 0 ;

} /* end of main () */

double calc_avg ( double t, double n )
{
   return t / n ;
} /* end of calc_avg () */

[code ends]
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
thiboAuthor Commented:
Thx for your help
But it has already been corrected in another way.
This is how the program is running right now:

[start code]
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
//#include "Car.h"


float calc_avg ( double, int ) ;


int main ( void )
{
   char line[82], temp1[10], temp2[10];
   double startkm, endkm, total = 0, last ;
   int no_of_trips = 0;
   float avg_trip_length ;
   int i, count;

   last = -1.0 ;

   while (fgets ( line, sizeof line, stdin ) != NULL )
   {
        //validate(...);
        i = 0; count = 0;
        while (line[i] != '\n' && line[i] != '\0') {
             if (line[i] == '\t') {
                  count++;
             }
             if ( i >= 79 )
             {
                  fprintf ( stderr, "\nThe input exceeds 80 characters. " ) ;
                  return EXIT_FAILURE;

             } /* end if, for */
             i++;
        }
        if (count != 4) /*not 4 blank-spaces: error*/
        {
             fprintf(stderr, "\nYou did not enter 5 fields. Error.");
             return EXIT_FAILURE;
        }      

      sscanf( line, "%*[^\t]%s %s%*[^\t]%*[^\n]",  temp1, temp2 );

      for (i = 0 ; temp1[i] != '\0' ; i++)
        {
          if (( ! isdigit ( temp1[i] )) && temp1[i] != '.')
          {
            fprintf( stderr, "\nNot a valid number. " ) ;
            return EXIT_FAILURE ;

             } // end if

        } // end for

        for (i = 0 ; temp2[i] != '\0' ; i ++ )
        {
          if (( ! isdigit ( temp2[i] )) && temp2[i] != '.')
          {
            fprintf( stderr, "\nNot a valid number. " );
            return EXIT_FAILURE ;

             } // end if

        } // end for      

    startkm = atof ( temp1 ) ;
    endkm = atof ( temp2 ) ;
   
      total += ( endkm - startkm ) ;

      if ( startkm >= endkm )
      {
         fprintf(stderr, "\nInvalid. Start km must be less than end km... " ) ;
         return EXIT_FAILURE;

      } /* end if */
   
      if ( startkm < last )
      {
         fprintf(stderr, "\nError! Start km in one record must be greater or less than end km of the previous record. " ) ;
         return EXIT_FAILURE;

      } /* end if */
      no_of_trips++ ;
      last = endkm ;

   } /* end while */

avg_trip_length = calc_avg( total, no_of_trips ) ;
printf( "\n Number of trips: %d \nTotal kilometres: %lf \n Average trip length: %f\n", no_of_trips, total , avg_trip_length ) ;


return 0 ;
                 
} /* end of main () */

float calc_avg ( double t, int n )
{
return  ( ( float ) t ) / n  ;

} /* end of calc_avg () */

[end code]

Its working ok now but i would like now to divide the program into 2 modules and a header file:

a stdin named car.c where the main is:
[code]
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "Car.h"

int main ( void )
{
      char line[82];
      int  last , total = 0 ;
      float startkm, endkm;
      int no_of_trips = 0;
      
      float avg_trip_length ;
      int i;
      int count;

      last = -1.0; /* date being checked when user will enter the first line */
      while ( fgets ( line, sizeof line, stdin ) != NULL )
      {
            validateInput(line);
      } /* end while */

 avg_trip_length = calc_avg( total, no_of_trips ) ;
 printf("\n Number of trips: %d \nTotal kilometres: %lf \n Average trip length: %f\n", no_of_trips, total , avg_trip_length);

 return 0 ;
                   
} /* end of main () */
[/code]

However, Im still having problem dividing the program into 2 parts....
The program should read from stdin (Standard Input)which would be in this case "Car.c" containing the main function.
After reading all input records, the program should print (stdout, standard output) the nb of trips, total nb of km and average trip length from another file named "validate.c". He should also check if there are any errors...
and to conclude a header..
This is what i did so far but get errors:

Car.c

[code]
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "Car.h"

int main ( void )
{
      char line[82];
      int  last , total = 0 ;
      float startkm, endkm;
      int no_of_trips = 0;
      
      float avg_trip_length ;
      int i;
      int count;

      last = -1.0; /* date being checked when user will enter the first line */
      while ( fgets ( line, sizeof line, stdin ) != NULL )
      {
            validateInput(line);
      } /* end while */

 avg_trip_length = calc_avg( total, no_of_trips ) ;
 printf("\n Number of trips: %d \nTotal kilometres: %lf \n Average trip length: %f\n", no_of_trips, total , avg_trip_length);

 return 0 ;
                   
} /* end of main () */
[/code]

validate.c

[code]

#include "Car.h"

int validateInput(char *line) {
int i, count;
char temp1[10], temp2[10];      
double startkm, endkm, total = 0, last;
int no_of_trips = 0;      
last = -1.0;      


      while (line[i] != '\n' && line[i] != '\0') {
            if (line[i] == '\t') {
                  count++;
            }
            if ( i >= 79 )
            {
                  fprintf( stderr, "\n The input exceeds 80 characters. " );
                  return EXIT_FAILURE;

            } /* end if, for */
            i++;
      }
      if (count != 4) /*not 4 blank-spaces: error*/
      {
            fprintf(stderr, "\nYou did not enter 5 fields. Error.");
            return EXIT_FAILURE;
      }       

   sscanf( line, "%*[^\t]%s %s%*[^\t]%*[^\n]", temp1, temp2 ) ;

   for (i = 0 ; temp1[i] != '\0' ; i++)
        {
          if (( ! isdigit ( temp1[i] )) && temp1[i] != '.')
          {
            fprintf( stderr, "\nNot a valid number. " ) ;
            return EXIT_FAILURE ;

             } // end if

        } // end for

        


      for (i = 0 ; temp2[i] != '\0' ; i ++ )
        {
            if (( ! isdigit ( temp2[i] )) && temp2[i] != '.')
            {
                      fprintf( stderr, "\nNot a valid number. " );
                        return EXIT_FAILURE ;
      
            } // end if

      } // end for      


      startkm = atof ( temp1 );
      endkm = atof ( temp2 );
   
   
   total += ( endkm - startkm );

   if ( startkm >= endkm )
   {
       fprintf(stderr, "\n Invalid. Start km must be less than end km... " );
       return EXIT_FAILURE;

   } /* end if */
 
   if ( startkm < last )
   {
       fprintf(stderr, "\nError! Start km in one record must be greater or less than end km of the previous record. " ) ;
       return EXIT_FAILURE;

   } /* end if */
   no_of_trips++ ;
   last = endkm;


      return ' ';
}

float calc_avg (double t, int n)
{
      return ((float) t) /n;
} /* end of calc_avg () */

[/code]

header named Car.h
[code]

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>


float calc_avg ( double, int ) ;
int validateInput(char *);

[/code]




0
adg080898Commented:
What error messages do you get?
0
thiboAuthor Commented:
its ok adq
working ok now
Thx a lot!
0
thiboAuthor Commented:
Hi!
This is how my program start (I managed to divid it into 2 modules and a header file):
<code>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "Validate.h"

int main ( void )
{
   char line[82];
   
   float avg_trip_length;
   
   /*If the program is finding an error from validate.c, it will exit from main*/
   while ( fgets ( line, sizeof line, stdin ) != NULL )
   {
        if(validateInput(line) == EXIT_FAILURE)
        {
             return EXIT_FAILURE;
        }


   } /* end while */

/* Get the average trip length from calc_avg and print all the details */

avg_trip_length = calc_avg( totalKM(), TotalTrips() );
printf("\n Number of trips: %d \nTotal kilometres: %f \n Average trip length: %f\n", TotalTrips(), totalKM() , avg_trip_length);

return 0;
               
} /* end of main () */

/* end of Car.c*/
/*******************************/

#include "Validate.h"

int no_of_trips = 0;
double total = 0;


int TotalTrips()
{
   return no_of_trips;
}


double totalKM()
{
   return total;
}


/*Check if the program is finding any errors. If there are no errors, the program will return EXIT_SUCCESS*/
int validateInput(char *line) {

   int i, count;
   char temp1[90], temp2[90];    
   double startkm, endkm;
   static double last;    
   count =0;
   i = 0;

   while (line[i] != '\n' && line[i] != '\0') {
        if (line[i] == '\t') {
             count++;
        }
        if ( i >= 79 )
        {
             fprintf( stderr, "\n The input exceeds 80 characters. " );
             return EXIT_FAILURE;

        } /* end if, for */
        i++;
   }
   if (count != 4) /*not 4 blank-spaces: error*/
   {
        fprintf(stderr, "\nYou did not enter 5 fields. Error ");
        return EXIT_FAILURE;
   }      

   sscanf( line, "%*[^\t]%s %s%*[^\t]%*[^\n]", temp1, temp2 );

   
   for(i = 0 ; temp1[i] != '\0' ; i++)
        {
       if (( ! isdigit ( (int)temp1[i] )) && (int)temp1[i] != '.')
       {
         fprintf( stderr, "\nNot a valid number. " ) ;
         return EXIT_FAILURE ;

          } // end if

     } // end for

   for(i = 0 ; temp2[i] != '\0' ; i ++ )
        {
        if (( ! isdigit ( (int)temp2[i] )) && (int)temp2[i] != '.')
        {
                 fprintf( stderr, "\nNot a valid number. " );
                  return EXIT_FAILURE ;
   
        } // end if

   } // end for      

   /* Converting string to double */

   startkm = atof ( temp1 );
   endkm = atof ( temp2 );


total += ( endkm - startkm );

if ( startkm >= endkm )
{
    fprintf(stderr, "\n Invalid. Start km must be less than end km... " );
    return EXIT_FAILURE;

} /* end if */

if ( startkm < last )
{
    fprintf(stderr, "\nError! Start km in one record > than end km of the previous record. " ) ;
    return EXIT_FAILURE;

} /* end if */
no_of_trips++; /*update numbers of trip */
last = endkm;


   return EXIT_SUCCESS;
}

/* Calcul the average trip length */
float calc_avg (double t, int n)
{
   return ((float) t) /n;
} /* end of calc_avg () */

/*end of validate.c*/

/************************************/

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>


float calc_avg ( double, int ) ;
int validateInput(char *);
int TotalTrips();
double totalKM();

</code>
/*********************************/
This program should read the log book from a file "opened for reading using buffered I/O":
Now I would like to add some details to it:
Add --> From To Distance Date, add a trip from "FROM" to "TO" with a given "DISTANCE" kilometres.
DEL --> Remove an edge from "FROM" to "TO". Print an error message if one or both of "FROM" or "TO" dont exist.
EXIT --> exit the program
SUMMARY --> Print a summary of all the trips so far, including the number of trips, the total number of km travelled, the avarge trip length, and the standard deviation of trip lengths.

The output for this log data should be:
Number of trips:
Total kilometres:
Average trip length:
Standard deviation: which is a measure of how spread out a distribution is. The standard deviation 's' is simply the square root of the variance, ie s=sqrt(s^2).

This is how the program is now running:
example of input:
Name-Startkm-endkm-date      -location
Bob  23000  23100 18/01/2004  NY
Tom  23100  23250 19/02/2001  London
Ann  23250  23280 20/03/2003  Berlin
Ann  23500  23550 22/06/2003  NY

The output after pressing control d:
Number of trips:        4
Total kilometres:     330
Average trip length:   82.5

This is what the output should add after average trip length
Standard deviation:    53.77

And if the user wants to add or delete some details or print summary (INPUT = prompt from the program):

INPUT: del  Berlin NY
INPUT: add Berlin NY 100 23/03/2003
INPUT: summary
Number of trips:        4
Total kilometres:     380
Average trip length:   95
Standard deviation:    49.33

Any idea? :)
0
jmcgOwnerCommented:
Nothing has happened on this question in more than 9 months. It's time for cleanup!

My recommendation, which I will post in the Cleanup topic area, is to
accept answer by adg (or delete as homework).

Please leave any comments here within the next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

jmcg
EE Cleanup Volunteer
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.