Main Page | Data Structures | File List | Data Fields | Globals

stringArray.c

Go to the documentation of this file.
00001 /* just some information about this file */
00002 #define STRINGARRAY_VERSION     "1.3.1"
00003 #define STRINGARRAY_DATE        "19-Dec-2003"
00004 
00005 /* structures and typedefs */
00006 
00007 /** @file
00008 * @anchor StringArray
00009 * Fault-tolerant structure to store one or more strings.
00010 *
00011 * This structure provides a fault-tolerant way to store several strings. Strings are stored in sequential
00012 * order with the function @ref StringArray_addElement. The individual elements are accessed via their
00013 * index @b starting @b from @b zero. Therefore, the index of the element with the highest index number
00014 * is one less than @c numberOfElements.
00015 *
00016 * The structure is created with @ref StringArray_create, destroyed with @ref StringArray_destroy and
00017 * displayed with @ref StringArray_display. The number of elements of a structure is returned by the
00018 * function @ref StringArray_getNumberOfElements, the size of the array @c arrayOfStrings is returned
00019 * by the function @ref StringArray_getSizeOfArray. Strings are added by @ref StringArray_addElement and
00020 * the value of an element is obtained by @ref StringArray_getElement. Elements that are identical to
00021 * a given string can be removed with @ref StringArray_removeElement.
00022 *
00023 * If an element is accessed via @ref StringArray_getElement and the index is higher than @c
00024 * numberOfElements - 1 (number of elements of this structure) the define @ref IndexOutOfBoundsError is
00025 * called and the program aborts.
00026 *
00027 * The size of @c arrayOfStrings can grow during the lifetime of a structure @ref StringArray. When a
00028 * structure @ref StringArray is created with @ref StringArray_create the initial size of @c
00029 * arrayOfStrings is set to @ref STRINGARRAY_STARTSIZEOFARRAY. @ref StringArray_addElement checks if @c
00030 * numberOfElements exceeds @c sizeOfArray and, if necessary, resizes the string array automatically via
00031 * @ref StringArray_extend. As there is currently no function to remove elements @c arrayOfStrings can
00032 * not shrink during the lifetime of an instance of @ref StringArray!
00033 *
00034 * @attention
00035 * Function @ref StringArray_addElement just links the given char* to @c arrayOfStrings. The char* is not
00036 * copied and therefore must not be freed after the assignment! If @ref StringArray_destroy is called the
00037 * memory of all elements in @c arrayOfStrings is freed automatically.
00038 *
00039 * <B>Description of the members:</B><BR><BR>
00040 * @c arrayOfStrings - array of char*<BR>
00041 * @c numberOfElements - number of elements in the structure<BR>
00042 * @c sizeOfArray - size of the array @c arrayOfStrings<BR>
00043 * @author Uli Fechner
00044 * @version 01/09/2003 - v1.0.0 - Uli Fechner - initial release
00045 * @version 02/09/2003 - v1.1.0 - Uli Fechner - major change: the size of the string array (@c arrayOfStrings) can
00046 * now grow during the lifetime of a structure @ref StringArray; this is handled automatically by @ref
00047 * StringArray_addElement if @c numberOfElements exceeds @c sizeOfArray; added @ref
00048 * STRINGARRAY_STARTSIZEOFARRAY, @ref StringArray_createWithSpecifiedArraySize and @ref
00049 * StringArray_extend; changes in @ref StringArray_create and StringArray_addElement
00050 * @version 08/09/2003 - v1.1.1 - Uli Fechner - small modification in the output format of @ref
00051 * StringArray_display
00052 * @version 08/09/2003 - v1.2.0 - Uli Fechner - bugfix related to the extension of the array (@ref
00053 * StringArray_addElement and @ref StringArray_extend); modified the headers of both functions
00054 * @version 15/10/2003 - v1.2.1 - Uli Fechner - changed the define @ref STRINGARRAY_STARTSIZEOFARRAY
00055 * @version 10/12/2003 - v1.2.2 - Uli Fechner - added function @ref StringArray_concatenate
00056 * @version 17/12/2003 - v1.3.0 - Uli Fechner - added function @ref StringArray_copy and @ref
00057 * StringArray_mapConcatenate
00058 * @version 19/12/2003 - v1.3.1 - Uli Fechner - added function @ref StringArray_removeElement
00059 * @@code
00060 */
00061 typedef struct
00062 {
00063         char** arrayOfStrings;
00064         int numberOfElements;
00065         int sizeOfArray;
00066 } StringArray;
00067 /** @endcode */
00068 
00069 
00070 /** A pointer to structure @ref StringArray is assigned the name @c StringArrayPtr. */
00071 typedef StringArray* StringArray_Ptr;
00072 
00073 /* defines */
00074 
00075 /** This value sets the size of @c arrayOfStrings if a new structure @ref StringArray is created.
00076 *
00077 * @author Uli Fechner
00078 * @version 02/09/2003 - Uli Fechner - initial release
00079 */
00080 #ifndef STRINGARRAY_STARTSIZEOFARRAY
00081 #define STRINGARRAY_STARTSIZEOFARRAY 50
00082 #endif
00083 
00084 /* function prototypes */
00085 
00086 StringArray_Ptr StringArray_create( void );
00087 
00088 StringArray_Ptr StringArray_createWithSpecifiedArraySize( const int sizeOfArray );
00089 
00090 void StringArray_destroy( StringArray_Ptr sAPtr );
00091 
00092 void StringArray_extend( const StringArray_Ptr sAPtr );
00093 
00094 void StringArray_display( StringArray_Ptr sAPtr, FILE* outputStream );
00095 
00096 StringArray_Ptr StringArray_copy( const StringArray_Ptr sAPtr );
00097 
00098 void StringArray_concatenate( const StringArray_Ptr sAPtrTarget, const StringArray_Ptr sAPtrSource );
00099 
00100 void StringArray_mapConcatenate( const StringArray_Ptr sAPtr, const char* source );
00101 
00102 int StringArray_getNumberOfElements( const StringArray_Ptr sAPtr );
00103 
00104 int StringArray_getSizeOfArray( const StringArray_Ptr sAPtr );
00105 
00106 void StringArray_addElement( const StringArray_Ptr sAPtr, char* string );
00107 
00108 char* StringArray_getElement( const StringArray_Ptr sAPtr, const int index );
00109 
00110 int StringArray_removeElement( StringArray_Ptr sAPtr, const char* string );
00111 
00112 /* functions */
00113 
00114 /** Creates a @ref StringArray structure.
00115 *
00116 * A @ref StringArray structure is created. The size of the array @c arrayOfStrings of the structure is
00117 * @ref STRINGARRAY_STARTSIZEOFARRAY and is dynamically adjusted during the lifetime of the structure.
00118 *
00119 * @attention
00120 * This function is only a wrapper for @ref StringArray_createWithSpecifiedArraySize
00121 *
00122 * @retval StringArray_Ptr pointer on the newly created structure @ref StringArray
00123 * @author Uli Fechner
00124 * @version 01/09/2003 - Uli Fechner - initial release
00125 * @version 02/09/2003 - Uli Fechner - major change: now, this function is a wrapper for @ref
00126 *                     StringArray_createWithSpecifiedArraySize; therefore, all instructions moved to
00127 *                     @ref StringArray_createWithSpecifiedArraySize
00128 */
00129 StringArray_Ptr StringArray_create( void )
00130 {
00131         return StringArray_createWithSpecifiedArraySize( STRINGARRAY_STARTSIZEOFARRAY );
00132 }
00133 
00134 /** Creates a @ref StringArray structure.
00135 *
00136 * A @ref StringArray structure is created. The size of the array @c arrayOfStrings of the structure is
00137 * given as an argument.
00138 *
00139 * @param sizeOfArray the size of the array @c arrayOfStrings of the newly created structure
00140 * @retval StringArray_Ptr pointer on the newly created structure @ref StringArray
00141 * @author Uli Fechner
00142 * @version 02/09/2003 - Uli Fechner - initial release
00143 */
00144 StringArray_Ptr StringArray_createWithSpecifiedArraySize( const int sizeOfArray )
00145 {
00146         StringArray_Ptr sAPtr;
00147         
00148         if( !( sAPtr = calloc( 1, sizeof( StringArray ) ) ) )
00149                 MemoryError( "sAPtr", "StringArray_createWithSpecifiedArraySize" );
00150         
00151         sAPtr->sizeOfArray = sizeOfArray;
00152         sAPtr->numberOfElements = 0;
00153         
00154         if( sizeOfArray == 0 )
00155                 sAPtr->arrayOfStrings = NULL;
00156         
00157         else
00158         {
00159                 if( !( sAPtr->arrayOfStrings = calloc( sizeOfArray, sizeof( char* ) ) ) )
00160                         MemoryError( "sAPtr->arrayOfStrings", "StringArray_createWithSpecifiedArraySize" );
00161         }
00162 
00163         return sAPtr;
00164 }
00165 
00166 /** Destroys a structure @ref StringArray.
00167 *
00168 * The structure @ref StringArray the pointer @c sAPtr refers to is destroyed. All allocated memory of
00169 * the structure is automatically freed; this includes the memory of the char* of @c arrayOfStrings.
00170 *
00171 * @param sAPtr pointer on the structure @ref StringArray that should be destroyed
00172 * @author Uli Fechner
00173 * @version 01/09/2003 - Uli Fechner - initial release
00174 */
00175 void StringArray_destroy( StringArray_Ptr sAPtr )
00176 {
00177         int counter;
00178         
00179         if( sAPtr != NULL )
00180         {
00181                 if( sAPtr->arrayOfStrings != NULL )
00182                 {
00183                         for( counter = 0; counter < sAPtr->numberOfElements; counter++ )
00184                         {
00185                                 if( (sAPtr->arrayOfStrings)[counter] != NULL )
00186                                         free ( (sAPtr->arrayOfStrings)[counter] );
00187                         }
00188                         free( sAPtr->arrayOfStrings );
00189                 }
00190                 free( sAPtr );
00191         }
00192         else
00193         {
00194                 fprintf( stderr, "\n\nERROR: Function 'StringArray_destroy' can not destroy a structure\n" );
00195                 fprintf( stderr, "'StringArray' that has not been created before!\n" );
00196                 AbortProgram;
00197         }
00198 }
00199 
00200 
00201 /** Extends the array size of a structure @ref StringArray.
00202 *
00203 * The array size of the structure @ref StringArray is enlarged (more exactly: its size is doubled). This
00204 * function is automatically called by @ref StringArray_addElement if @c numberOfElements exceeds @c
00205 * sizeOfArray.
00206 *
00207 * @param sAPtr pointer on the structure @ref StringArray containing the array that is extended
00208 * @author Uli Fechner
00209 * @version 02/09/2003 - Uli Fechner - initial release
00210 * @version 08/09/2003 - Uli Fechner - function rewritten from scratch; function header modified
00211 */
00212 void StringArray_extend( const StringArray_Ptr sAPtr )
00213 {
00214         int counter; /* counter to enumerate the elements of arrayOfIntegers */
00215         char** newArrayOfStrings; /* replaces iAPtr->arrayOfStrings */
00216         
00217         /* create new integer array with doubled size compared to iAPtr->arrayOfString */
00218         if( !( newArrayOfStrings = calloc( 2 * sAPtr->sizeOfArray, sizeof( char* ) ) ) )
00219                 MemoryError( "newArrayOfStrings", "StringArray_extend" );
00220         
00221         /* copy information from sAPtr->arrayOfStrings to newArrayOfStrings */
00222         for( counter = 0; counter < sAPtr->numberOfElements; counter++ )
00223                 newArrayOfStrings[counter] = (sAPtr->arrayOfStrings)[counter];
00224         sAPtr->sizeOfArray *= 2;
00225         
00226         /* destroy sAPtr->arrayOfStrings */
00227         if( sAPtr->arrayOfStrings != NULL )
00228                 free( sAPtr->arrayOfStrings );
00229         
00230         sAPtr->arrayOfStrings = newArrayOfStrings;
00231 }
00232 
00233 /** Displays a structure @ref StringArray.
00234 *
00235 * The structure @ref StringArray the pointer @c sAPtr refers to is displayed on the FILE* @c
00236 * outputStream.
00237 *
00238 * @param sAPtr pointer on the structure @ref StringArray that is displayed
00239 * @param outputStream FILE* on the stream the output is sent to
00240 * @author Uli Fechner
00241 * @version 01/09/2003 - Uli Fechner - initial release
00242 * @version 08/09/2003 - Uli Fechner - small modifications in the output format
00243 */
00244 void StringArray_display( StringArray_Ptr sAPtr, FILE* outputStream )
00245 {
00246         int counter; /* simple counter variable in for loop */
00247         
00248         if( sAPtr == NULL )
00249         {
00250                 fprintf( outputStream, "The Structure 'StringArray' (pointer: %p) does not exist.\n\n", sAPtr );
00251                 return;
00252         }
00253 
00254         if( sAPtr->numberOfElements == 0 )
00255         {
00256                 fprintf( outputStream, "The Structure 'StringArray' (pointer: %p) is empty.\n\n", sAPtr );
00257                 return;
00258         }
00259 
00260         for( counter = 0; counter < sAPtr->numberOfElements; counter++ )
00261                 fprintf( outputStream, "%s\t", (sAPtr->arrayOfStrings)[counter] );
00262         //fprintf( outputStream, "\n" );
00263 }
00264 
00265 /** A deepcopy of @c sAPtr is returned.
00266 *
00267 * @attention
00268 * Empty strings (NULL) are not copied. The number of elements of the @b copy of @c sAPtr may
00269 * therefore be less than the number of elements of @c sAPtr.
00270 *
00271 * @param sAPtr a deepcopy of the strings of @c sAPtr is returned
00272 * @retval StringArray_Ptr deepcopy of @c sAPtr
00273 * @author Uli Fechner
00274 * @version 17/12/2003 - Uli Fechner - initial release
00275 */
00276 StringArray_Ptr StringArray_copy( const StringArray_Ptr sAPtr )
00277 {
00278         int counter;
00279         char* currentSourceElement;
00280         char* tempString;
00281         StringArray_Ptr copyOfSAPtr;
00282         
00283         copyOfSAPtr = StringArray_create( );
00284         
00285         for( counter = 0; counter < sAPtr->numberOfElements; counter++ )
00286         {
00287                 currentSourceElement = StringArray_getElement( sAPtr, counter );
00288                 if( currentSourceElement != NULL )
00289                 {
00290                         if( !( tempString = calloc( strlen( currentSourceElement ) + 1, sizeof( char ) ) ) )
00291                                 MemoryError( "tempString", "StringArray_copy" );
00292                         strncpy( tempString, currentSourceElement, strlen( currentSourceElement ) + 1 );
00293                         StringArray_addElement( copyOfSAPtr, tempString );
00294                 }
00295         }
00296         return copyOfSAPtr;
00297 }
00298 
00299 /** A copy of each string in @c sAPtrSource is added to @c sAPtrTarget.
00300 *
00301 * @attention
00302 * Empty strings (NULL) are not copied. The number of elements that are added to @c sAPtrTarget may
00303 * therefore be less than the number of elements that are added to @c sAPtrSource.
00304 *
00305 * @param sAPtrTarget copies of the strings of @c sAPtrSource are added to this structure @ref StringArray
00306 * @param sAPtrSource copies of the strings of this structure @ref StringArray are added to @c sAPtrSource
00307 * @author Uli Fechner
00308 * @version 10/12/2003 - Uli Fechner - initial release
00309 */
00310 void StringArray_concatenate( const StringArray_Ptr sAPtrTarget, const StringArray_Ptr sAPtrSource )
00311 {
00312         int counter;
00313         char* currentSourceElement;
00314         char* tempString;
00315         
00316         for( counter = 0; counter < sAPtrSource->numberOfElements; counter++ )
00317         {
00318                 currentSourceElement = StringArray_getElement( sAPtrSource, counter );
00319                 if( currentSourceElement != NULL )
00320                 {
00321                         if( !( tempString = calloc( strlen( currentSourceElement ) + 1, sizeof( char ) ) ) )
00322                                 MemoryError( "tempString", "StringArray_concatenate" ); 
00323                         strncpy( tempString, currentSourceElement, strlen( currentSourceElement ) + 1 );
00324                         StringArray_addElement( sAPtrTarget, tempString );
00325                 }
00326         }
00327 }
00328 
00329 /** @c source is added to each element (char*) of @c sAPtr.
00330 *
00331 * @attention
00332 * Notrhing is added to empty strings (NULL).
00333 *
00334 * @param sAPtr each element of @c sAPtr is modified
00335 * @param source this char* is concatenated to each element of @c sAPtr
00336 * @author Uli Fechner
00337 * @version 17/12/2003 - Uli Fechner - initial release
00338 */
00339 void StringArray_mapConcatenate( const StringArray_Ptr sAPtr, const char* source )
00340 {
00341         int counter;
00342         char* currentElement;
00343         char* tempTargetString; 
00344 
00345         for( counter = 0; counter < sAPtr->numberOfElements; counter++ )
00346         {
00347                 currentElement = StringArray_getElement( sAPtr, counter );
00348                 if( currentElement != NULL )
00349                 {
00350                         if( !( tempTargetString = calloc( strlen( currentElement ) + strlen( source ) + 1, \
00351                                 sizeof( char ) ) ) )
00352                                 MemoryError( "tempTargetString", "StringArray_mapConcatenate" );
00353                         strncpy( tempTargetString, currentElement, strlen( currentElement ) + 1 );
00354                         strncat( tempTargetString, source, strlen( source ) + 1 );
00355                         (sAPtr->arrayOfStrings)[ counter ] = tempTargetString;
00356                         free( currentElement );
00357                 }
00358         }               
00359 }
00360 
00361 /** Returns the number of elements of a structure @ref StringArray.
00362 *
00363 * The number of elements of the structure @ref StringArray the pointer @c sAPtr refers to is returned.
00364 *
00365 * @param sAPtr pointer on the structure @ref StringArray of which the number of elements is returned
00366 * @retval int number of elements of the structure @ref StringArray
00367 * @author Uli Fechner
00368 * @version 01/09/2003 - Uli Fechner - initial release
00369 */
00370 int StringArray_getNumberOfElements( const StringArray_Ptr sAPtr )
00371 {
00372         return sAPtr->numberOfElements;
00373 }
00374 
00375 /** Returns the size of the array @c arrayOfStrings of a structure @ref StringArray.
00376 *
00377 * The size of the array @c arrayOfStrings of the structure @ref StringArray is returned.
00378 *
00379 * @param sAPtr pointer on the structure @ref StringArray of which the size of the array is returned
00380 * @retval int size of the array @c arrayOfStrings of the structure @ref StringArray
00381 * @author Uli Fechner
00382 * @version 01/09/2003 - Uli Fechner - initial release
00383 */
00384 int StringArray_getSizeOfArray( const StringArray_Ptr sAPtr )
00385 {
00386         return sAPtr->sizeOfArray;
00387 }
00388 
00389 /** A char* is added to the structure @ref StringArray.
00390 *
00391 * The char* is added to the array @c arrayOfStrings of structure @ref StringArray.
00392 * If the array @c arrayOfStrings is already full (i.e. @c numberOfElements >= @c sizeOfArray)
00393 * it is extended by calling the function @ref StringArray_extend.
00394 *
00395 * @param sAPtr pointer on the structure @ref StringArray the char* is added to
00396 * @param string char* that is added to @ref StringArray
00397 * @author Uli Fechner
00398 * @version 01/09/2003 - Uli Fechner - initial release
00399 * @version 02/09/2003 - Uli Fechner - added the capability to extend @c arrayOfStrings if necessary;
00400 *                     therefore, @b const of @c sAPtr had to be removed
00401 * @version 08/09/2003 - Uli Fechner - fixed a bug related to the function call @ref StringArray_extend;
00402 * function header modified (const added)
00403 */
00404 void StringArray_addElement( const StringArray_Ptr sAPtr, char* string )
00405 {
00406         if( sAPtr->numberOfElements >= sAPtr->sizeOfArray )
00407                 StringArray_extend( sAPtr );
00408 
00409         (sAPtr->arrayOfStrings)[(sAPtr->numberOfElements)] = string;
00410         (sAPtr->numberOfElements)++;
00411 }
00412 
00413 /** The char* of the element with index @c index of structure @ref StringArray is returned.
00414 *
00415 * The value of the element with index @c index of the structure @ref StringArray @c sAPtr points on is
00416 * returned. If the index @c index is greater than (@c numberOfElements - 1 ), the program aborts with
00417 * the call of the define @ref IndexOutOfBoundsError.
00418 *
00419 * @param sAPtr pointer on the structure @ref StringArray that contains the char*
00420 * @param index index of the char* that is returned
00421 * @retval char* the char* with index @c index
00422 * @author Uli Fechner
00423 * @version 01/09/2003 - Uli Fechner - initial release
00424 */
00425 char* StringArray_getElement( const StringArray_Ptr sAPtr, const int index )
00426 {
00427         if( index < sAPtr->numberOfElements )
00428                 return (sAPtr->arrayOfStrings)[ index ];
00429         else
00430                 IndexOutOfBoundsError( "StringArray", sAPtr->numberOfElements, index );
00431 }
00432 
00433 /** All elements of @c sAPtr that are identical to @c string are removed.
00434 *
00435 * Elements that are identical to @c string are removed from @c sAPtr. The return value is the number
00436 * of times @c string is found in @c sAPtr.
00437 *
00438 * @param sAPtr @c string is removed from the structure @ref StringArray that is referred to by @c sAPtr
00439 * @param string all occurrences of string are removed from @c sAPtr
00440 * @retval int number of times @c string was removed from @c sAPtr
00441 * @author Uli Fechner
00442 * @version 19/12/2003 - Uli Fechner - initial release
00443 */
00444 int StringArray_removeElement( StringArray_Ptr sAPtr, const char* string )
00445 {
00446         StringArray_Ptr newSAPtr; /* new StringArray: all elements that equal string are removed */
00447         int counter; /* simple counter in for loop */
00448         int stringFound = 0; /* stores the number of times string is found within sAPtr */
00449         
00450         for( counter = 0; counter < sAPtr->numberOfElements; counter++ )
00451         {
00452                 if( strcmp( sAPtr->arrayOfStrings[ counter ], string ) == 0 )
00453                 {
00454                         stringFound++;
00455                         free( sAPtr->arrayOfStrings[ counter ] );
00456                         sAPtr->arrayOfStrings[ counter ] = NULL;
00457                 }
00458         }
00459         newSAPtr = StringArray_copy( sAPtr );
00460         StringArray_destroy( sAPtr );
00461         sAPtr = newSAPtr;
00462 
00463         return stringFound;
00464 }

Generated on Tue Nov 9 16:27:11 2004 for retroflux by doxygen 1.3.6