Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

Parse.C

Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2000-2002, Jelle Kok, University of Amsterdam
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without 
00006 modification, are permitted provided that the following conditions are met:
00007 
00008 1. Redistributions of source code must retain the above copyright notice, this 
00009 list of conditions and the following disclaimer. 
00010 
00011 2. Redistributions in binary form must reproduce the above copyright notice, 
00012 this list of conditions and the following disclaimer in the documentation 
00013 and/or other materials provided with the distribution. 
00014 
00015 3. Neither the name of the University of Amsterdam nor the names of its 
00016 contributors may be used to endorse or promote products derived from this 
00017 software without specific prior written permission. 
00018 
00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
00020 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
00021 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00022 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 
00023 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
00024 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
00025 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
00026 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
00027 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
00028 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029 */
00046 #include "Parse.h"
00047 
00048 #include <ctype.h>    // needed for isdigit
00049 #include <math.h>     // needed for pow
00050 #include <string.h>   // needed for strlen
00051 
00052 /******************************************************************************/
00053 /*********************** CLASS PARSE ******************************************/
00054 /******************************************************************************/
00055 
00062 char Parse::gotoFirstNonSpace( char** strMsg )
00063 {
00064   while(*strMsg && isspace(**strMsg) )
00065     (*strMsg)++;
00066   return  (*strMsg) ?  **strMsg : '\0';
00067 
00068 }
00069 
00078 char Parse::gotoFirstSpaceOrClosingBracket( char** strMsg )
00079 {
00080   while( *strMsg && **strMsg!=' ' && **strMsg!=')' )
00081     (*strMsg)++;
00082   return  (*strMsg) ?  **strMsg : '\0';
00083 }
00084 
00091 int Parse::gotoFirstOccurenceOf( char c, char** strMsg )
00092 {
00093   int i=0;
00094   while(**strMsg && **strMsg != c )
00095   {
00096     i++;
00097     (*strMsg)++;
00098   }
00099   if( ! **strMsg )
00100     return -1;
00101   return i;
00102 }
00103 
00111 int Parse::parseFirstInt( char** strMsg )
00112 {
00113   int  iRes  = 0;
00114   bool bIsMin= false;
00115   char *str  = *strMsg;
00116 
00117   while( *str != '\0' && !isdigit(*str) && *str!='-')
00118     str++;                             // walk to first non digit or minus sign
00119 
00120 
00121   if( *str != '\0' && *str=='-')       // if it was a minus sign, remember
00122   {
00123     bIsMin=true;
00124     str++;
00125   }
00126 
00127   while( *str != '\0' && *str<='9' && *str>='0' )   // for all digits
00128   {
00129       iRes=iRes*10+(int)(*str-'0');                 // multiply old res with 10
00130       str++;                                        // and add new value
00131   }
00132   *strMsg = str;
00133   return (bIsMin) ? -iRes : iRes;
00134 }
00135 
00144 double Parse::parseFirstDouble( char** strMsg )
00145 {
00146   double dRes=0.0, dFrac=1.0;
00147   bool bIsMin=false, bInDecimal=false, bCont=true;
00148   char *str = *strMsg;
00149 
00150   // go to first part of double (digit, minus sign or '.')
00151   while( *str != '\0' && !isdigit(*str) && *str!='-' && *str!='.')
00152   {
00153     // when NaN or nan is double value, return -1000.0
00154     if( (*str=='N' && strlen(str)>3 && *(str+1)=='a' && *(str+2)=='N') ||
00155         (*str=='n' && strlen(str)>3 && *(str+1)=='a' && *(str+2)=='n') )
00156     {
00157       *strMsg = str+3;
00158       return -1000.0;
00159     }
00160     else
00161        str++;
00162   }
00163 
00164   if( *str != '\0' && *str=='-')               // if minus sign, remember that
00165   {
00166     bIsMin=true;
00167     str++;
00168   }
00169 
00170   while( *str != '\0' && bCont)                // process the number bit by bit
00171   {
00172     if( *str=='.' )                            // in decimal part after '.'
00173       bInDecimal = true;
00174     else if( bInDecimal && *str<='9' && *str>='0') // number and in decimal
00175     {
00176       dFrac=dFrac*10.0;                        // shift decimal part to right
00177       dRes += (double)(*str-'0')/dFrac;        // and add number
00178     }
00179     else if( *str<='9' && *str>='0' )          // if number and not decimal
00180       dRes=dRes*10+(double)(*str-'0');         // shift left and add number
00181     else if( *str=='e' ) // 10.6e-08           // if to power e
00182     {
00183       if( *(str+1) == '+' )                    // determine sign
00184         dRes *=  pow(10, parseFirstInt(&str)); // and multiply with power
00185       else if( *(str+1) == '-' )
00186       {
00187         str = str+2;                           // skip -
00188         dRes /=  pow(10, parseFirstInt(&str)); // and divide by power
00189       }
00190       bCont = false;                           // after 'e' stop
00191     }
00192     else
00193       bCont = false;                           // all other cases stop
00194 
00195     if( bCont == true )                        // update when not stopped yet
00196       str++;
00197   }
00198   *strMsg = str;
00199   return (bIsMin && dRes != 0.0) ? -dRes : dRes;
00200 }
00201 
00202 /******************************************************************************/
00203 /********************** TESTING PURPOSES *************************************/
00204 /******************************************************************************/
00205 /*
00206 #include<iostream.h>
00207 
00208 int main( void )
00209 {
00210   double d = 13.6e+15;
00211   char str[] = "13.6e+15";
00212   double d2 = 13.6e-15;
00213   char str2[] = "13.6e-15";
00214 
00215   char *strmsg;
00216   strmsg = &str[0];
00217   cout  << d << endl;
00218   cout << Parse::parseFirstDouble( &strmsg )<< endl;
00219   strmsg = &str2[0];
00220   cout  << d2 << endl;
00221   cout << Parse::parseFirstDouble( &strmsg ) << endl;
00222   return 0;
00223 }
00224 */

Generated on Tue Jul 2 10:18:52 2002 for UvA Trilearn 2002 by doxygen1.2.12 written by Dimitri van Heesch, © 1997-2001