extracting a sub section of the string

Vlearns
Vlearns used Ask the Experts™
on
i have a  const char* p whose value is printed as below:

(gdb) p p
$5 = 0x1394510 "(HEADER MESSAGE-ID <8d8vhsk5qqpfl7lyetqsbdsb.1264020499132@email.android.com>)"


where  
p is defined and initialized as
const char* p = str.c_str();

i need to extract 8d8vhsk5qqpfl7lyetqsbdsb.1264020499132@email.android.com into a string or a const * variable

how do i do that in the best efficient way?

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Try this:
	string str = "(HEADER MESSAGE-ID <8d8vhsk5qqpfl7lyetqsbdsb.1264020499132@email.android.com>)";
	const char* p = str.c_str();
	char * t = const_cast<char*>(p);
	string result;
	char * ptr;
	t = strtok_r(t, "<", &ptr);
	t = strtok_r(NULL, ">", &ptr);
	result = t;
	cout << result << endl;

Open in new window

Looking at that, I would rather copy str into a new string to avoid any const literal string issues. I'll revise this.
I am not sure why the above version works on cygwin. I would have thought that the constant literal string would not allow modification by strtok_r. So, I copied the original string into a new area.
	string str = "(HEADER MESSAGE-ID <8d8vhsk5qqpfl7lyetqsbdsb.1264020499132@email.android.com>)";
	char* p = (char *)malloc( str.size() + 1 );
	string result;
	char * ptr;
	strncpy( p, str.c_str(), str.size() + 1 );
	p = strtok_r(p, "<", &ptr);
	result = strtok_r(NULL, ">", &ptr);
	free(p);
	cout << result << endl;

Open in new window

OWASP: Forgery and Phishing

Learn the techniques to avoid forgery and phishing attacks and the types of attacks an application or network may face.

When using strtok_r, you should check to see if the returned value is NULL. If NULL, then the delimiter was not found, and you stop processing the string.
If you do not define p as you said, then I think this is a cleaner version:
	string str = "(HEADER MESSAGE-ID <8d8vhsk5qqpfl7lyetqsbdsb.1264020499132@email.android.com>)";
	string result;
	int bpos, epos;
	if( ( (bpos = str.find("<") )!= string::npos ) &&
		( (epos = str.find(">") )!= string::npos ) &&
		  (bpos < epos) ) {
		result = str.substr( bpos+1, epos - bpos -1 );
	}
	else {
		cout << "<> pair not found" << endl;
	}
	cout << "result = " << result << endl;

Open in new window

evilrixSenior Software Engineer (Avast)

Commented:
phoffric,

You can simplify your last code sample by starting the second find from bpos, meaning you won't need the bpos < epos check.

-Rx.
good point :)
Looks C++ Builder...
You can use the following since your text is inside <>.
Assuming "$5 = 0x1394510 "(HEADER MESSAGE-ID <8d8vhsk5qqpfl7lyetqsbdsb.1264020499132@email.android.com>)" is the original string inside AnsiString S.
S = S.Delete(AnsiPos("<",S));//delete all characters BEFORE "<"... To delete AND "<" then use AnsiPos ("<",S)+1...
S.SetLength(AnsiPos(">",S);// Cut all trailing characters...
S = S.Trim();// to get rid of empty characters at beginning and end...

George Tokas.
Something is missing:
S.SetLength(AnsiPos(">",S);// Cut all trailing characters...
it is:
S.SetLength(AnsiPos(">",S));

George Tokas.

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