Thread: Problem with arrays and pointers

  1. #1
    Dupek
    Guest

    Problem with arrays and pointers

    Im stuck with a problem I need to do for one of my classes...After doing a count I have to declare a char pointer array of the token count size dynamically. In the function findTokens() I have to search through the string, put the address of each token into the pointer array, and change the colon separator to the null character. This is what I got but it doesn't want to work...Any help out there?
    Code:
    //...
    int main(void)
    {
     //local declerations
     char theString[] = "abcd0001:groupno:userno:name:/bin/ksh";
     char colon=':';
     int count;
     count = countToken(theString,colon);
      cout << " Number of tokens in string are: " << count;
     char **ptr;
     ptr = new char*[count];
     blah = findTokens(theString, ptr,colon);
     for (int j=0; j < 6; j++)
     {
     cout << " Token "<<j<<": " <<blah <<endl<<endl;
     }
    }//main
    
    int countToken(char theString[], char colon)
    {
      int count = 1;  // Initialise at one
      int len = strlen(theString);
      for(int n = 0; n < len; n++)  // Loop from character zero to end of string
      {
        if (theString[n] == colon) // Check characters one by one
        {
          count++;
        }
      }
      return count;
    }
    char findTokens(char* theString, char **ptr, char colon)
    {
     int index=0;
     **ptr[index] = *theString;
     index++;
       while(*theString)
       {
          if(*theString == colon)
          {
           **ptr[index] = (*theString + 1);
          *theString = '\0';
          }
    
       *theString++;
       }
       return;
    }

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    Your indirection was off and a few things needed to be shuffled. The changes needed were minor:
    Code:
    #include <iostream>
    
    using namespace std;
    
    int countToken(char theString[], char colon)
    {
      int count = 1;  // Initialise at one
      int len = strlen(theString);
      for(int n = 0; n < len; n++)  // Loop from character zero to end of string
      {
        if (theString[n] == colon) // Check characters one by one
        {
          count++;
        }
      }
      return count;
    }
    void findTokens(char* theString, char **ptr, char colon)
    {
      int index=0;
    
      ptr[index++] = theString;
    
      while(*theString)
      {
        if(*theString == colon)
        {
          *theString = '\0';
          ptr[index++] = (theString + 1);
        }
        
        theString++;
      }
      return;
    }
    
    int main(void)
    {
      //local declarations
      char theString[] = "abcd0001:groupno:userno:name:/bin/ksh";
      char colon=':';
      int count;
      
      count = countToken(theString,colon);
      cout << "Number of tokens in string are: " << count <<endl;
      
      char **ptr;
      ptr = new char*[count];
      
      findTokens(theString, ptr,colon);
      
      for (int j=0; j < count; j++)
      {
        cout << " Token "<<j<<": " <<ptr[j] <<endl<<endl;
      }
    }//main
    -Prelude
    My best code is written with the delete key.

  3. #3
    Dupek
    Guest

    Talking

    Thanks so much Prelude!!!!

  4. #4
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    I don't have my compiler to try the following function, but I think there are some problems in it anyway. See comments.
    Code:
    void findTokens(char* theString, char **ptr, char colon)
    {
      int index=0;
    
      ptr[index++] = theString;
    
      //you can't assign one Cstyle string to another, use strcpy() instead
      //each ptr[index] needs to have memory declared.  You need another loop with call to new operator to do this, probably back in main()
      //you don't want to assign the entire length of theString to ptr[0] either, you want just the firtst token from theString in ptr[0] 
      
    
      while(*theString)//this looks for the null char at end of theString
      {
    
        if(*theString == colon)//this looks for a colon in the theString
        {
    
          *theString = '\0';//this replaces the colon with a null char
    
          ptr[index++] = (theString + 1);
          //this assigns theString, minus the current token to the next string in ptr, but it doesn't leave just the first token in ptr[index]; it leaves whatever theString was when theString was passed to ptr[index] in ptr[index] so:
         ptr[0] will be "abcd0001:groupno:userno:name:/bin/ksh"
         ptr[1] will be "groupno:userno:name:/bin/ksh"
         ptr[2] will be "userno:name:/bin/ksh"
         etc.
    
        }//end if
        
        theString++;
      }//end while
      return;
    I hope that I have my thinking cap on correctly this AM, but sometimes it comes off when I am not looking, so use a compiler to try out the function---don't take me at my word.

    If I am correct here's my algorithm for finding tokens and storing one token per string in ptr.

    I would declare a tempString and use a different counter variable to keep track of where I am in tempString.

    I would read each char into tempString from theString until I found a colon.

    I would place a nul char in tempString instead of a colon

    I would then assign tempString to ptr[index++]

    I would then reset the counter variable for tempString to 0.

    I would then move on to the next char in theString.

  5. #5
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >//you can't assign one Cstyle string to another, use strcpy() instead
    You're thinking about arrays, this is simple pointer addressing. The assignment is perfectly legal.

    >//each ptr[index] needs to have memory declared.
    It already is declared, the list of pointers point to different parts of theString.

    >ptr[0] will be "abcd0001:groupno:userno:name:/bin/ksh"
    >ptr[1] will be "groupno:userno:name:/bin/ksh"
    >ptr[2] will be "userno:name:/bin/ksh"
    No, remember that the colon is replaced with a nul character.

    ptr[0] will be "abcd0001"
    ptr[1] will be "groupno"
    ptr[2] will be "userno"
    etc...

    This is a simple and common technique, a list of pointers reference locations in a single block of memory so that it isn't lost. When the function starts the string looks like this:

    "abcd0001:groupno:userno:name:/bin/ksh"

    After the function runs, theString and ptr will look like this:
    Code:
           "abcd0001\0groupno\0userno\0name\0/bin/ksh"
            ^         ^        ^       ^     ^
            |         |        |       |     |
    ptr[0]---         |        |       |     |
    ptr[1]-------------        |       |     |
    ptr[2]----------------------       |     |
    ptr[3]------------------------------     |
    ptr[4]------------------------------------
    -Prelude
    My best code is written with the delete key.

  6. #6
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    Prelude: fascinating. Your explanation was wonderful. I'll copy and run the program later.

    Dupek and Prelude: Thanks for the opportunity to improve my understanding. It's why I keep coming back.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pointers and multi dimensional arrays
    By andrea72 in forum C++ Programming
    Replies: 5
    Last Post: 01-23-2007, 04:49 PM
  2. Problem with arrays, pointers and functions when combined
    By The Wazaa in forum C++ Programming
    Replies: 2
    Last Post: 02-05-2006, 10:44 AM
  3. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  4. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  5. Crazy memory problem with arrays
    By fusikon in forum C++ Programming
    Replies: 9
    Last Post: 01-15-2003, 09:24 PM