finding patterns in a string

Hi,

I was working on a magnetic card reader and it alwats gives me the information something like this

%B1234567890123456^FNAME/LNAME^05/05

where the string after %B till the ^ character is the account number

how do i parse information from the string. I need a way which can parse the information somethng like this

accno:1234567890123456
name: FNAME LNAME
exp date: 05/05

How do i do this? thanks in advance


jyotishbAsked:
Who is Participating?
 
puranik_pCommented:
You can you this function for this.

int SplitString( CString& input, CString& delimiter, CStringArray& results)
{
      int iPos = -1;
      int newPos = -1;
      int sizeS2 = delimiter.GetLength();
      int isize = input.GetLength();

      vector<int> positions;

      newPos = input.Find (delimiter, 0);

      if( newPos < 0 ) { return 0; }

      int numFound = 0;

      while( newPos > iPos )
      {
            numFound++;
            positions.push_back(newPos);
            iPos = newPos;
            newPos = input.Find (delimiter, iPos+sizeS2+1);
      }

      for( int i=0; i <= positions.size(); i++ )
      {
            CString s;
            if( i == 0 ) { s = input.Mid( i, positions[i] ); }
            int offset = positions[i-1] + sizeS2;
            if( offset < isize )
            {
                  if( i == positions.size() )
                  {
                        s = input.Mid(offset);
                  }
                  else if( i > 0 )
                  {
                        s = input.Mid( positions[i-1] + sizeS2, positions[i] - positions[i-1] - sizeS2 );
                  }
            }
            if( s.GetLength() > 0 )
            {
                  s.TrimLeft();
                  s.TrimRight();
                  results.Add(s);
            }
      }
      return numFound;
}


You can use it like this:

CStringArray strArr, strArr2;
strArr.RemoveAll();
strArr2.RemoveAll();
CString strInput = "%B1234567890123456^FNAME/LNAME^05/05"
SplitString(strInput, "%",strArr);

if(strArr.GetSize()>0)
{
   for(int j=0; j<strArr.GetSize(); j++)
   {
        CString strInput2 = strArr.GetAt(j);
       if(strInput2.Find("^") != -1)
       {
             SplitString(strInput2,"^", strArr2)
            for(k=....
          {
             //This way u can format as many internal section as you want
           }
       }
   }

}
0
 
jyotishbAuthor Commented:
uhhoooooooooo  :-s..... thanx.. but do we have to write such a long code for that?  anyways. ur long code scared me and i thought i would write something on my own.. let me know if the following code should work...thank you anyways



char *args[10]={NULL};
      char delim[]="%^/";
      
      
      char *strch=str.GetBuffer(0);
      int len = strlen(strch);
      
      
      int i=0;
      char * token = NULL;
      token=strtok(strch,delim);
      
      args[i++]=token;
      while(1)
      {
            
                     token=strtok(NULL,delim);
               if(token==NULL)
            break;
              else
            args[i++]=token;
      }      

str.ReleaseBuffer();
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
mahesh1402Commented:
if you refer this simple class CToken : http://www.codeguru.com/Cpp/Cpp/string/manip/article.php/c2805/

#include "Token.h"

//Then you are free to create and use an instance of CToken. For example:

CString str = "A B C D"
CString newTok;
CToken tok(str);
tok.SetToken(" "); // Set whatever token you need to extract ^ or %.......etc
while(tok.MoreTokens())
{
   newTok = tok.GetToken()
}

-MAHESH
0
 
puranik_pCommented:
The function SplitString() you can directly copy in your code.
You don't need to write it again and again.
Every time when you want to parse your string for a delimeter you can just call it.
like this:

SplitString(strInput, "%",strArr);
0
 
puranik_pCommented:
You code is not correct.
Because it will first search for the whole string. i.e. "%^" does not exist in your string.

--%B1234567890123456^FNAME/LNAME^05/05

Your token value will be NULL.
It is possible by strtok.
If you want to use strtok then you will also have to go through heavy iteration.

So if you want to work with many delimiters at a time, then u can efficienty use SplitString().
0
 
jyotishbAuthor Commented:
yes..i got it worked now.. I will try urs too.. thanx
0
 
DanRollinsCommented:
When I know exactly what to expect in the data and I know exactly what I'm looking for, I just hard-code it like this:

    CString sRawData="%B1234567890123456^FNAME/LNAME^05/05"; // from the input device
    CString sAcctNum="";

    int nOffsetStart= sRawData.Find( "%B" ) {   // eg, 0
        if ( nOffsetStart != -1 ) {
            nOffsetStart += 2;  // Get past the "%B" eg, 2
            int nOffsetEnd= sRawData.Find("^") {
            if ( nOffsetEnd != -1 ) {  // eg, 18
               sAcctNum= sRawData.Mid( nOffsetStart,  nOffsetEnd-nOffsetStart );  // eg, len 16
            }
    }
   // if sAcctNum > "" then the Acct Num was found.

However, Since you are looking for multiple items in the string, the general-purpose routines provided by the other Experts above are probably a better solution.
0
 
mahesh1402Commented:
split
0
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.

All Courses

From novice to tech pro — start learning today.