Solved

Substring with start and end

Posted on 2014-10-21
8
289 Views
Last Modified: 2014-10-24
Hi folks, I'm trying to understand a little bit better the string and in this case substring set within C and C++.

What I need is to retrieve the Text typed into a TEdit Box, for example an email, and get the substring from the beggining to the "@" and display it on another TEdit Box, and everything after the "@" in a third TEdit Box when I click on a Button. So it would separate the "user", the "Domain" and the "@".

I tried but since the value retrieved from the TEdit Box is Unicode the string and substring that I tried didn't work.

By the way I'm using XE6 C++ Builder.

Any help owuld be much appreciated. Cheers!
0
Comment
Question by:Rodric MacOliver
8 Comments
 
LVL 33

Expert Comment

by:sarabande
ID: 40394145
TEdit Box is Unicode the string and substring that I tried didn't work.

you may try the following:

#include <string>
...
std::wstring strEdit = strYourEditString;

std::wstring strPart1, strPart2;

size_t pos = strEdit.find(L'@');
if (pos != std::wstring::npos)
{
       strPart1 = strEdit.substr(0, pos);
       strPart2 = strEdit.substr(pos+1);
}
else
{
     strPart1 = strEdit;
}

Open in new window

}
you could assign a wstring to variables of your string class like

yourstring = wstr.c_str();

Open in new window


Sara
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 40394155
I agree with Sara, but I would suggest do a more convenient parsing to filter out wrong mail addresses, i.e.
bool ParseMail( const std::wstring& address, std::wstring& name, std::wstring& domain )
{
	if ( address.find_first_of( L"{[()]}\\/|<>:;,.\t " ) != std::wstring::npos )
	{
		// fail if one of the above characters appear (this maybe not a complete list, to
		// be honest I don't know all characters not allowd in a mail address from the scratch
		return false;
	}

	std::wstring::size_type pos = address.find( L"@" );

	if ( pos == std::wstring::npos )
	{
		// '@' not found
		return false;
	}

	if ( pos == 0 || pos == address.length() - 1 )
	{
		// found '@' at start or end
		return false;
	}

	if ( address.find( L"@", pos + 1 ) != std::wstring::npos )
	{
		// more than one '@' found
		return false;
	}

	name = address.substr( 0, pos );
	domain = address.substr( pos + 1 );

	return true;
}

Open in new window

This can be used like this:

   std::wstring name, domain;
   if ( ParseMail( strYourEditString, name, domain ) == false )
   {
    // handle error
   }
  else
  {
   // use the strings name and domain as you need
  }

Hope that helps,

ZOPPO
0
 
LVL 9

Expert Comment

by:Subrat (C++ windows/Linux)
ID: 40396173
TEdit->Name returns UnicodeString. So you have to convert it to std:string/wstring, then pass that to the function provided by ZOPPO and sara.Use the following function for conversion.

// Convert wstring to UnicodeString
String ToUniStr(const std::wstring &str)
{
   char *cBuf = new char[str.length()+1];
   memset( cBuf, 0, str.length()+1);

   wcstombs(cBuf, str.c_str(), str.length());

   String aBuf = cBuf;
   delete[] cBuf;
   return aBuf;
}

In my opinion, use sara's solution in your first attempt though you are in learning stage.
But latter use ZOPPO's solution which is more robost.

Please let us know if you need any clarifications on the above codes.
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 

Author Comment

by:Rodric MacOliver
ID: 40399116
Unfortunately neither work, still give me the error for Unicode and String...
I'm still trying so any other help would be appreciated...
Cheers
0
 
LVL 33

Accepted Solution

by:
sarabande earned 500 total points
ID: 40399664
can you post the code that doesn't work and a pointer to the statement which doesn't compile?

if using class UnicodeString it has member function c_str which returns const wchar_t * what is a pointer to a wide character string. then the following code should work:

#include <string>
...
std::wstring strEdit = strYourUnicodeString.c_str();

std::wstring strPart1, strPart2;

size_t pos = strEdit.find(L'@');
if (pos != std::wstring::npos)
{
       strPart1 = strEdit.substr(0, pos);
       strPart2 = strEdit.substr(pos+1);
}
else
{
     strPart1 = strEdit;
}
UnicodeString ustr1 = strPart1.c_str();
UnicodeString ustr2 = strPart2.c_str();

Open in new window


if not using UnicodeString but AnsiString or 'char *' then you would use std::string and not std::wstring.

#include <string>
...
std::string strEdit = strYourAnsiString.c_str();

std::string strPart1, strPart2;

size_t pos = strEdit.find('@');
if (pos != std::string::npos)
{
       strPart1 = strEdit.substr(0, pos);
       strPart2 = strEdit.substr(pos+1);
}
else
{
     strPart1 = strEdit;
}
AnsiString str1 = strPart1.c_str();
AnsiString str2 = strPart2.c_str();

Open in new window


if you have a TEdit variable you would get the text by member function TEdit::WindowText().

to find out whether the WindowText returns wide char pointer or char pointer, you may try to compile the statements:

// assume you have pointer to TEdit (pEdit)
wchar_t * pwsz = pEdit->WindowText();
char * psz = pEdit->WindowText();

Open in new window


only one of these statements will compile and you would know which type is required.

Sara
0
 

Author Comment

by:Rodric MacOliver
ID: 40400378
Sorry Sara, I'm not that good at C++ since I'm just starting to study it, so maybe I'm doing something completely stupid. :)

Here goes teh code:

	std::wstring strEdit = email->Text.c_str();

	std::wstring strPart1, strPart2;

	size_t pos = strEdit.find(L'@');
	if (pos != std::wstring::npos)
	{
		   strPart1 = strEdit.substr(0, pos);
		   user->Text = strPart1;                                    //ERROR POINTS HERE
		   strPart2 = strEdit.substr(pos+1);
		   domain->Text = strPart2;
	}
	else
	{
		 strPart1 = strEdit;
	}
	UnicodeString ustr1 = strPart1.c_str();
	UnicodeString ustr2 = strPart2.c_str();

Open in new window


The error says:
[bcc32 Error] Unit1.cpp(31): E2034 Cannot convert 'wstring' to 'UnicodeString'
  Full parser context
    Unit1.cpp(21): parsing: void _fastcall TForm1::Button1Click(TObject *)
0
 

Author Closing Comment

by:Rodric MacOliver
ID: 40401156
I was mixing it up with the code and got it to work. Thanks a lot for the insights.
0
 
LVL 33

Expert Comment

by:sarabande
ID: 40401765
great.

i assume the statement

user->Text = strPart1;

Open in new window

was the wrong one which failed cause C++ Builder API  doesn't take std:.wstring bit a pointer to wchar_t instead.

so the statement

user->Text = strPart1.c_str();

Open in new window

should compile.

Sara
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
designing in object programming 12 94
Please explain C language error codes ? 5 28
Gaming Software 1 19
Finding Divisors 5 20
Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question