Parse a string in WxWidgets from Card Reader

Rocco Galati
Rocco Galati used Ask the Experts™
on
I'm developing a WxWidgets application under Ubuntu and I'm using CodeBlocks as IDE.

I need to:

  • read the data stored in a magnetic card band
  • check if they are OK
  • parse the string in order to get the code, the name and the surname

I'm using a USB magnetic card reader and I set a TextCtrl as "focused" so it immediately gets the data from the reader automatically.

The format of the string is like this:

%URSMCC84R04E815LURSO  MARCO_ò8038001605011036724_

Open in new window


The control characters are always the same and I need to read everything between % and _.
I need to obtain three strings:
  • the first one containing the first 16 chars
  • the second contains the surname which goes from the 17th till the first space
  • the third string contains the name and goes from the first char after the space till the _

What is the best way to do this in Wxwidgets?
Moreover, since the reader emulates a keyboard, the output string is read a char at a time, so how can I design the parsing code?

This is the code I'm using to read the string.

void ProjectFrame::OntesseraText(wxCommandEvent& event)
{
    wxString stringa_tessera = tessera->GetValue(); // I read the string coming from the USB reader
    TextCtrl2->ChangeValue( stringa_tessera ); // I load the string in the second TextCtrl just for test
}

void ProjectFrame::OnTextCtrl2Text(wxCommandEvent& event)
{
// TextCtrl used to display the parsed string
}

Open in new window


I see that there is a class wxStringTokenizer, should I use it?
I'm sorry but I'm just a beginner :(

Thank you!
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Top Expert 2016

Commented:
when using wxString you may use code like

wxString number = stringa_tessera.Left(16);
wxString rest = stringa_tessera.Mid(16);
wxString surname = rest.BeforeFirst(wxUniChar(' '));
rest = rest.AfterFirst(wxUniChar(' '));
wxString name = rest.BeforeFirst(wxUniChar('_'));

Open in new window


note, this might throw exceptions if the input string is not valid.

using a tokenizer is possible but probably makes it more difficult if the parsing is as simple as you described.

Sara
Rocco GalatiR&D Engineer

Author

Commented:
Hello Sarabande and thank you for your support!

I did some tests with your example code, but I think I need to make some modifications since I'm only able to correctly extract the name.

I get:
number: %URSMCC84R04E815 // the final L is missing

name: MARCO
surname: LURSO // it should be URSO
rest: MARCO_ò8038001605011036724_

The number is always composed by 16 chars while the name and the surname can change in length.
I tried to change the number of chars in Left() and Mid() but there is always some missing char unfortunately.

void ProjectFrame::OntesseraText2(wxCommandEvent& event)
{
    wxString stringa_tessera = tessera->GetValue();
    // I read the string coming from the USB reader

    wxString number = stringa_tessera.Left(16);
    wxString rest = stringa_tessera.Mid(16);
    wxString surname = rest.BeforeFirst(wxUniChar(' '));
    rest = rest.AfterFirst(wxUniChar(' '));
    wxString name = rest.BeforeFirst(wxUniChar('_'));

    rest_ctrl->ChangeValue( rest );
    name_ctrl->ChangeValue( name );
    surname_ctrl->ChangeValue( surname );
    number_ctrl->ChangeValue( number );
}

Open in new window

Top Expert 2016

Commented:
ok. the % character is not part of the 16-char 'number' and therefore surname is 'URSO' (and not "LURSO").

    wxString number = stringa_tessera.MID(1, 16);  // Mid starts at offset 1 and takes 16 chars
    wxString rest = stringa_tessera.Mid(17);                         // consider the leading % 
    wxString surname = rest.BeforeFirst(wxUniChar(' '));   // now it should be "URSO"
    rest = rest.AfterFirst(wxUniChar(' '));
    wxString name = rest.BeforeFirst(wxUniChar('_'));

Open in new window


Sara
How to Generate Services Revenue the Easiest Way

This Tuesday! Learn key insights about modern cyber protection services & gain practical strategies to skyrocket business:

- What it takes to build a cloud service portfolio
- How to determine which services will help your unique business grow
- Various use-cases and examples

Rocco GalatiR&D Engineer

Author

Commented:
Thank you again, Sara!

Unfortunately, it is not working very well since it still mix the chars :(

it should be:

number: URSMCC84R04E815L
name: MARCO
surname: URSO

and it should remove everything else.

I'm also trying to use wxStringTokenizer but it is not easy to implement for me to be honest.
Top Expert 2016
Commented:
stringa_tessera.MID(1, 16); 

Open in new window


that was a typing error. should be stringa_tessera.Mid(1, 16);

i assume that the wrong statement didn't compile and therefore your test used the old program version.

if it is still wrong you might print the string 'stringa_tessera' and post it here.

Sara
Rocco GalatiR&D Engineer

Author

Commented:
Thank you a lot, Sara!
It works very well! I think the error with in the uppercase instruction.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial