Solved

# finding patterns in a string

Posted on 2006-05-05
Medium Priority
208 Views
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

0
Question by:jyotishb
• 3
• 3
• 2
• +1

LVL 14

Accepted Solution

puranik_p earned 672 total points
ID: 16612634
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();
}
}
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

Author Comment

ID: 16612677
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

LVL 22

Assisted Solution

mahesh1402 earned 664 total points
ID: 16612701
0

LVL 22

Expert Comment

ID: 16612736
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

LVL 14

Expert Comment

ID: 16612740
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

LVL 14

Expert Comment

ID: 16612778
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

Author Comment

ID: 16612813
yes..i got it worked now.. I will try urs too.. thanx
0

LVL 49

Assisted Solution

DanRollins earned 664 total points
ID: 16686451
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

LVL 22

Expert Comment

ID: 16883306
split
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar ā letās display the timestamp there.  We need to get the timestamp from the document sā¦
Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view ā CGridButton should be visible as a class.  Rā¦
This Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
###### Suggested Courses
Course of the Month13 days, 23 hours left to enroll