Thread: Need Some Understanding

  1. #1
    Registered User
    Join Date
    Mar 2010
    Posts
    2

    Need Some Understanding

    Hi,
    I need some help here, i've been writing some
    code for an assignment and it is mostly about
    pointers and string manipulations. It runs but
    crashes and I think it might be from over-
    valuating some strings maybe not. I have
    written in check points to make sure each
    function passes through but quits at
    findFirstPath loop, I had kept running the
    program through as i added more and more
    code. It had stopped when I near finished I
    believed it to just be because I hadn't finished
    the functions I called.

    Any clarification would be awesome.
    Thanks

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    
    /* The following matrix defines how compounds 
    (labelled A to T) can be synthesised to other compounds.  The first letter in each 
    row is a starting compound, and each subsequent letter gives the list of 
    compound to which this starting compound can be synthesised.  So the 
    string "OIJN" indicates that compound O can be converted to componds I, J, or N. Note 
    that compounds that cannot be synthesisedto any other compound do not have a 
    corresponding string in the matrix.
    */
    
    #define MAXSTRING 10  // maximum length of 
    the synthesis string.
    char synthesisMatrix[][MAXSTRING] =
    {
         "BAH",
         "DCI",
         "EJ",
         "FK",
         "GFLM",
         "HBDG",
         "ICJ",
         "JEO",
         "KFL",
         "LF",
         "MQ",
         "NJ",
         "OIJN",
         "QMP",
         "RQS",
         "SMT",
         ""
    };  // Note that last entry is the empty string, which means that the last row can be 
        // detected when the first character in the row is the '\0' (nul) character. This
        // means that is is not necessary to know the number of rows in the matrix.
        
    // Some definitions
    #define TRUE 1
    #define FALSE 0
    #define MAXNUMCOMPOUNDS 26 // No more 
    than 26 compounds defined
    #define MINCOMPOUND 'A'  // Smallest letter 
    for compound
    #define MAXCOMPOUND 'T'  // Maximum 
    letter for compound
    
    // Prototypes
    int userInterface(char *, char *);
    void findFirstPath(char *, char , char );
    char findNextCompound(char *, char *);
    char *findSynthesisString(char );
    void printSynthesisPath(char *);
    
    /*-------------------------------------------------------------------------
    Function: main
    Description: Overall control of the program. 
    Calls userInterface to get input from the user. When userInterface returns FALSE, it
    signals the end of the program.  If it returns TRUE, then
    it has provided values for initialCompound and finalCompound and
    calls findFirstPath to try to find a path. If a path is foundcall printSynthesisPath to print the results, otherwise print message that path could not be found.
    ---------------------------------------------------------------------------*/
    int main()
    {
        char 
    pathString[MAXNUMCOMPOUNDS+1]; // char array for storing path
        char initialCompound;  // character for initial compound
        char finalCompound;  // character for final compound
        int flag;  // flag for controlling the loop
        
        do
        {
           flag = userInterface(&initialCompound, &finalCompound);
           if(flag==TRUE)
           {
              findFirstPath(pathString, initialCompound, finalCompound);
              if(*pathString != '\0')
                 printSynthesisPath(pathString);
              else
                 printf("Synthesis path could not be found\n"); 
           }
        } while(flag!=FALSE);
        printf("Terminating...\n");
        system("pause");
    }
    /*-------------------------------------------------------------------------
    Function: userInterface
    Description: Gets input from the user. This 
    function should return either TRUE or FALSE.  If it returns TRUE, 
    then two different characters should have been obtained from the 
    user and saved using thepointers.
    --------------------------------------------------------------------------*/
    int userInterface(char *initialPtr, char *finalPtr)
    {
        int choice;//This will decide return value
        printf("What would you like to do?\n1)Enter in First and Last Compound?\n2)Exit\n");
        do{
        scanf("%d", &choice);
        if(choice==2){
                      return FALSE;
                      }
        else if(choice<1 || choice>2){
             printf("please choose 1 or 2\n");
             }
        if(choice==1){
             fflush(stdin);
             printf("OK! Now enter first compound : (A-T)\n");
             while(*initialPtr<MINCOMPOUND || *initialPtr>MAXCOMPOUND){
                                   fflush(stdin);
                                   scanf("%c", initialPtr);
                                   if(*initialPtr<MINCOMPOUND || *initialPtr>MAXCOMPOUND){
                                                      printf("WRONG Enter in between A-T\n");
                                                                        }
                                                  }
             printf("Now the Second compound : (A-T)\n");
             while(*finalPtr<MINCOMPOUND || *finalPtr>MAXCOMPOUND){
                                 fflush(stdin);
                                 scanf("%c", finalPtr);
                                 if(*finalPtr<'A' || *finalPtr>'Z'){
                                                      printf("WRONG Enter in between A-T\n");
                                                                        }
                                                }
             printf("\n%c   %c\n", *initialPtr, *finalPtr);
             return TRUE;
             }
        }while(choice!=1&&choice!=2);
    }
    /*-------------------------------------------------------------------------
    Function: findFirstPath
    Description: The principal function to find a synthesis path. 
    --------------------------------------------------------------------------*/
    void findFirstPath(char *pathPtr, char 
    initialCompound, char finalCompound)
    {
         char *alreadySeenPtr, alreadySeenArray[MAXSTRING], *currentPtr, *synthesisPtr, nextCompound;//Assigning Arrays/Pointers
         int flag;//flag for control of loop
         
         alreadySeenPtr=alreadySeenArray;
         *alreadySeenPtr='\0';
         currentPtr=pathPtr;
         *currentPtr=initialCompound;
         *(currentPtr+1)='\0';
         flag=TRUE;
         while(flag==TRUE){
                           if(strchr(alreadySeenPtr, *currentPtr)==NULL){
                                                     *alreadySeenPtr=*currentPtr;
                                                     alreadySeenPtr++;
                                                     *alreadySeenPtr='\0';
                                                     }
                           synthesisPtr=findSynthesisString(*currentPtr);
                           if(strchr(synthesisPtr, finalCompound)!=NULL){
                                                   currentPtr++;
                                                   *currentPtr=finalCompound;
                                                   *(currentPtr+1)='\0';
                                                   flag=FALSE;
                                                   }
                           else{
                                nextCompound=findNextCompound(synthesisPtr, alreadySeenPtr);
                                if(nextCompound!='\0'){
                                                       currentPtr++;
                                                       *currentPtr=nextCompound;
                                                       *(currentPtr+1)='\0';
                                                       }
                                else{
                                     if(*currentPtr==initialCompound){
                                                                      *currentPtr='\0';
                                                                      flag=FALSE;
                                                                      }
                                     else{
                                          *currentPtr='\0';
                                          currentPtr--;
                                          }
                                     }
                                }
                           }
         printf("\nCheck firstPath\n");
    }
    /*-------------------------------------------------------------------------
    Function: findNextCompoundDescription: Finds next compound in a synthesis path that has not yetbeen seen. Returns the nul character if all compounds in the synthesis path are in the already seen array.
    --------------------------------------------------------------------------*/
    char findNextCompound(char *synthesisPtr, 
    char *alreadySeenPtr)
    {
        char *searchPath, *alreadySearched, character;
        int flag;
        
        searchPath=synthesisPtr;
        alreadySearched=alreadySeenPtr;
        flag=TRUE;
        
        while(flag==TRUE){
                          if(strchr(searchPath, *alreadySearched)==NULL){
                                                *(alreadySearched+1)=*searchPath;
                                                *searchPath='\0';
                                                }
                          if(strchr(searchPath, *alreadySearched)!=NULL){
                                                character='\0';
                                                return character;
                                                flag=FALSE;
                                                     }
                          
                          }
    
    }
    /*-------------------------------------------------------------------------
    Function: findSynthesisString Description: Finds the synthesis string in the 
    synthesisMatrix (i.e. row) for a given compound.
    --------------------------------------------------------------------------*/
    char *findSynthesisString(char compound)
    {
         char first, *firstPtr, *rowaddress;
         int flag;
         
         first=compound;
         firstPtr=&synthesisMatrix[MAXNUMCOMPOUNDS][FALSE];
         rowaddress=strchr(firstPtr, first);
         if(*rowaddress==first){
                                return rowaddress;
                                }
         if(*rowaddress!=first){
                                rowaddress=strchr(firstPtr, '\0');
                                return rowaddress;
                                }
         printf("\nCheck SynthesisString\n");
    }
    /*-------------------------------------------------------------------------
    Function: printSynthesisPath Description: Prints a synthesis path in the 
    form of A->B->H (when path is defined as "ABH". Guard against receiving an empty string.
    --------------------------------------------------------------------------*/
    void printSynthesisPath(char *pathPtr)
    {
         char *printPath;
         int i;
         
         printPath=pathPtr;
         
         printf("The Path is :\n");
         for(i=0;i<=MAXSTRING-1; i++){
                                 printf("%c->",*(printPath+i));
                                 }
         printf("\nCheck Print");   
    }

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Add debug printf() statements to isolate the code segment that crashes.
    Alternatively you can step through the executable using the gdb debugger.

  3. #3
    Registered User
    Join Date
    Mar 2010
    Posts
    2
    I went through a debugging process and found that a problem was most with finding the address of the first character path.

    I've solved that now it is able to figure out if the path is possible or not, but now my new problem is that once i have my path I need to print the following path.

    Doesn't sound hard, I know I'm just missing something like for example I enter in the 2 compounds and say B, and H are my compounds and the path is BAH. I need to put it through as B->A->H though i have it as B->H.

    Any Ideas?
    New code is :
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    
    /* The following matrix defines how compounds (labelled A to T) can be synthesised
       to other compounds.  The first letter in each row is a starting compound, and
       each subsequent letter gives the list of compound to which this starting 
       compound can be synthesised.  So the string "OIJN" indicates that compound O can
       be converted to componds I, J, or N. Note that compounds that cannot be synthesised
       to any other compound do not have a corresponding string in the matrix.
    */
    
    #define MAXSTRING 10  // maximum length of the synthesis string.
    char synthesisMatrix[][MAXSTRING] =
    {
         "BAH",
         "DCI",
         "EJ",
         "FK",
         "GFLM",
         "HBDG",
         "ICJ",
         "JEO",
         "KFL",
         "LF",
         "MQ",
         "NJ",
         "OIJN",
         "QMP",
         "RQS",
         "SMT",
         ""
    };  // Note that last entry is the empty string, which means that the last row can be 
        // detected when the first character in the row is the '\0' (nul) character. This
        // means that is is not necessary to know the number of rows in the matrix.
        
    // Some definitions
    #define TRUE 1
    #define FALSE 0
    #define MAXNUMCOMPOUNDS 26 // No more than 26 compounds defined
    #define MINCOMPOUND 'A'  // Smallest letter for compound
    #define MAXCOMPOUND 'T'  // Maximum letter for compound
    
    // Prototypes
    int userInterface(char *, char *);
    void findFirstPath(char *, char , char );
    char findNextCompound(char *, char *);
    char *findSynthesisString(char );
    void printSynthesisPath(char *);
    
    /*-------------------------------------------------------------------------
    Function: main
    Description: Overall control of the program. Calls userInterface to get
                 input from the user. When userInterface returns FALSE, it
                 signals the end of the program.  If it returns TRUE, then
                 it has provided values for initialCompound and finalCompound and
                 calls findFirstPath to try to find a path. If a path is found
                 call printSynthesisPath to print the results, otherwise
                 print message that path could not be found.
    ---------------------------------------------------------------------------*/
    int main()
    {
        char pathString[MAXNUMCOMPOUNDS+1]; // char array for storing path
        char initialCompound;  // character for initial compound
        char finalCompound;  // character for final compound
        int flag;  // flag for controlling the loop
        
        do
        {
           flag = userInterface(&initialCompound, &finalCompound);
           if(flag==TRUE)
           {
              findFirstPath(pathString, initialCompound, finalCompound);
              if(*pathString != '\0')
                 printSynthesisPath(pathString);
              else
                 printf("Synthesis path could not be found\n"); 
           }
        } while(flag!=FALSE);
        printf("Terminating...\n");
        system("pause");
    }
    /*-------------------------------------------------------------------------
    Function: userInterface
    Description: Gets input from the user. This function should return either
                 TRUE or FALSE.  If it returns TRUE, then two different characters
                 should have been obtained from the user and saved using the
                 pointers.
    --------------------------------------------------------------------------*/
    int userInterface(char *initialPtr, char *finalPtr)
    {
        int choice;//This will decide return value
        printf("What would you like to do?\n1)Enter in First and Last Compound?\n2)Exit?\n");
        do{
        scanf("%d", &choice);
        if(choice==2){
                      return FALSE;
                      }
        else if(choice<1 || choice>2){
             printf("please choose 1 or 2\n");
             }
        if(choice==1){
             fflush(stdin);
             printf("OK! Now enter first compound : (A-T)\n");
             while(*initialPtr<MINCOMPOUND || *initialPtr>MAXCOMPOUND){
                                   fflush(stdin);
                                   scanf("%c", initialPtr);
                                   if(*initialPtr<MINCOMPOUND || *initialPtr>MAXCOMPOUND){
                                                      printf("WRONG Enter in between A-T\n");
                                                                        }
                                                  }
             printf("Now the Second compound : (A-T)\n");
             while(*finalPtr<MINCOMPOUND || *finalPtr>MAXCOMPOUND){
                                 fflush(stdin);
                                 scanf("%c", finalPtr);
                                 if(*finalPtr<'A' || *finalPtr>'Z'){
                                                      printf("WRONG Enter in between A-T\n");
                                                                        }
                                                }
             printf("\n%c   %c\n", *initialPtr, *finalPtr);
             return TRUE;
             }
        }while(choice!=1&&choice!=2);
    }
    /*-------------------------------------------------------------------------
    Function: findFirstPath
    Description: The principal function to find a synthesis path. 
    --------------------------------------------------------------------------*/
    void findFirstPath(char *pathPtr, char initialCompound, char finalCompound)
    {
         char *alreadySeenPtr, alreadySeenArray[MAXSTRING], *currentPtr, *synthesisPtr, nextCompound;//Assigning Arrays/Pointers
         int flag;//flag for control of loop
         
         alreadySeenPtr=alreadySeenArray;
         *alreadySeenPtr='\0';
         currentPtr=pathPtr;
         *currentPtr=initialCompound;
         *(currentPtr+1)='\0';
         flag=TRUE;
         while(flag==TRUE){
                           if(strchr(alreadySeenPtr, *currentPtr)==NULL){
                                                     *alreadySeenPtr=*currentPtr;
                                                     alreadySeenPtr++;
                                                     *alreadySeenPtr='\0';
                                                     }
                           synthesisPtr=findSynthesisString(*currentPtr);
                           if(strchr(synthesisPtr, finalCompound)!=NULL){
                                                   currentPtr++;
                                                   *currentPtr=finalCompound;
                                                   *(currentPtr+1)='\0';
                                                   flag=FALSE;
                                                   }
                           else{
                                nextCompound=findNextCompound(synthesisPtr, alreadySeenPtr);
                                if(nextCompound!='\0'){
                                                       currentPtr++;
                                                       *currentPtr=nextCompound;
                                                       *(currentPtr+1)='\0';
                                                       }
                                else{
                                     if(*currentPtr==initialCompound){
                                                                      *currentPtr='\0';
                                                                      flag=FALSE;
                                                                      }
                                     else{
                                          *currentPtr='\0';
                                          currentPtr--;
                                          }
                                     }
                                }
                           }
         printf("\nCheck firstPath\n");
    }
    /*-------------------------------------------------------------------------
    Function: findNextCompound
    Description: Finds next compound in a synthesis path that has not yet
                 been seen. Returns the nul character if all compounds
                 in the synthesis path are in the already seen array.
    --------------------------------------------------------------------------*/
    char findNextCompound(char *synthesisPtr, char *alreadySeenPtr)
    {
        char *searchPath, *alreadySearched, character;
        int flag;
        
        searchPath=synthesisPtr;
        alreadySearched=alreadySeenPtr;
        flag=TRUE;
        
        while(flag==TRUE){
                          if(strchr(searchPath, *alreadySeenPtr)!=NULL){
                                                
                                                flag=FALSE;
                                                     }
                          if(strchr(synthesisPtr, *alreadySeenPtr)==NULL){
                                                *(alreadySearched+1)=*searchPath;
                                                *searchPath='\0';
                                                }
                          
                          
                          }
    
    }
    /*-------------------------------------------------------------------------
    Function: findSynthesisString
    Description: Finds the synthesis string in the synthesisMatrix (i.e. row)
                 for a given compound.
    --------------------------------------------------------------------------*/
    char *findSynthesisString(char compound)
    {
         char first, *firstPtr, *rowaddress;
         int flag,i;
         
         first=compound;
         
         for(i=0; i<MAXNUMCOMPOUNDS; i++){
                  rowaddress=memchr(synthesisMatrix[i], first, 1);     
                  if(rowaddress!=NULL){
                                       printf("\nCheck SynthesisString\naddress: %d character: %c\n", rowaddress, first);      
                                       return rowaddress;
                                       break;
                                         }
                  }
         
        
    }
    /*-------------------------------------------------------------------------
    Function: printSynthesisPath
    Description: Prints a synthesis path in the form of A->B->H (when path is
                 defined as "ABH". Guard against receiving an empty string.
    --------------------------------------------------------------------------*/
    void printSynthesisPath(char *pathPtr)
    {
         char *printPath;
         int i, length;
         
         printPath=pathPtr;
         length=strlen(pathPtr);
         
         printf("The Path is :\n");
         for(i=0;i<=length; i++){
                                 printf("%c",printPath[i]);
                                 if(i<length-1){
                                              printf("->");
                                              }
                                 }
         printf("\nCheck Print\n");   
    }

  4. #4
    Registered User slingerland3g's Avatar
    Join Date
    Jan 2008
    Location
    Seattle
    Posts
    603
    Not sure you really need the "", entry in your array of strings you have declared. Also you have stipulated a constant "MAXNUMCOMPOUNDS = 26" yet your compounds are from 'A' to 'T'. Are you sure you are not looping past this when searching?

    From what I gather you are only needed to test if your compound is at the beginning of any one of your strings? ie synthesisMatrix[0][0], synthesisMatrix[1][0]. You only need to compare the first char in each string to your compound under test...right?

    Out of curiosity, I see that J can be synthesized to N, per your example, but can N be synthesized to J from another sequence?Just a logic question I have as I see that is possible from your array of strings.

    Also you are only needing to look at the first char of each string and not that the compound is within the string at all? If that is the case a simple loop through your array of array of chars is all that is needed to compare the first char to your compound IMHO.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help understanding a problem
    By dnguyen1022 in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2009, 04:21 PM
  2. Replies: 9
    Last Post: 01-03-2009, 03:48 PM
  3. Understanding Headers
    By AeonMoth in forum C++ Programming
    Replies: 2
    Last Post: 06-27-2007, 05:53 AM
  4. trouble understanding the source file structure
    By Mario F. in forum C++ Programming
    Replies: 5
    Last Post: 05-26-2006, 06:46 PM
  5. understanding recursive functions
    By houler in forum C Programming
    Replies: 7
    Last Post: 12-09-2004, 12:56 PM