|
Kevin McFarlane wrote:
Regular expressions are unreadable.
As is C++, C# and Japanese, for people who don't know them. I agree that they can take a moment to work through, but they are hardly unreadable.
Kevin McFarlane wrote:
1. It worked using a tool such as Expresso.
2. I had to change the syntax to get it to work in VS.
3. I couldn't get either the origibal or the changed syntax to work in TextPad.
TextPad ? I agree that it's a pain that you need to mangle regex to get it to work in the IDE. But Expresso regex will work in C#/VB.NET code, no hassles. I do it all the time.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
C++ and C# resemble something like ordinary English. (Though I'd prefer those languages to be even more readable than they are.) Regular Expressions don't. Mentally you just have to do a lot more work to understand them.
Re: Expresso, I was referring to RegEx search in the Search/Replace dialog. There I found there were differences.
Perhaps it's just a mindset thing. It's probably why I detest Perl. Though it's not just the RegEx why I hate Perl. But I think Perl is one of those languages you either love or hate depending on your mental makeup. My current boss loves Perl. He didn't seem to mind when I said I hated it.
Kevin
|
|
|
|
|
Kevin McFarlane wrote:
Re: Expresso, I was referring to RegEx search in the Search/Replace dialog. There I found there were differences.
Yeah I know. Like I said, I hate that, too.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
Great.. thanks for all your input.
I also wrote a small method that will strip all the spaces from the end of an basic_string up until is reaches text.
So a string like "This is a test " .. would be
"This is a test" once the method is complete.
Something is not working correctly though.
typedef std::string::size_type size_type;
std::string AnyString;
char MySpace = ' ';
size_type CHAR_INDEX;
CHAR_INDEX = AnyString.size();//AnyString.rfind(MySpace);
for (size_type i = CHAR_INDEX;AnyString[i]== MySpace; i--)
AnyString.erase(i,1);
The above source only works when stripping one space, like from
"2003 " to "2003".
If i have "2003 ", it does not work. Can anyone tell me what i am doing wrong here?
|
|
|
|
|
LCI wrote:
for (size_type i = CHAR_INDEX;AnyString[i]== MySpace; i--)
AnyString.erase(i,1);
The above source only works when stripping one space, like from
"2003 " to "2003".
If i have "2003 ", it does not work. Can anyone tell me what i am doing wrong here?
You probably want a 'trim_back()' function. It must also work for 'unusual' cases like empty strings and strings that contain only white space. Also note that string::size_type is unsigned (cannot be less than 0).
#include <string>
#include <iostream>
std::string& trim_back (std::string& str)
{
using namespace std;
while (str.size()) {
if (isspace (str[str.size()-1])) {
str.erase(str.size()-1);
} else {
break;
}
}
return str;
}
int main()
{
using namespace std;
string test ("2003 "),
whitespaceOnly (" \n\t"),
empty;
cout << '|' << trim_back(test) << '|' << endl;
cout << '|' << trim_back(whitespaceOnly) << '|' << endl;
cout << '|' << trim_back(empty) << '|' << endl;
return 0;
}
|
|
|
|
|
I recommend you look at boost. I recently installed it and it is a fantastic library. It includes string trimming functions - e.g.:
#include <boost/algorithm/string.hpp>
...
std::string str = "Hello ";
boost::trim(str);
|
|
|
|
|
Try
inline string trim_right(const string& source, const string& t = " ")
{
string str = source;
return str.erase(source.find_last_not_of(t) + 1);
}
inline string trim_left(const string& source, const string& t = " ")
{
string str = source;
return str.erase(0, source.find_first_not_of(t));
}
inline string trim(const string& source, const string& t = " ")
{
return trim_left(trim_right(source, t), t);
}
Kevin
|
|
|
|
|
Kevin McFarlane wrote:
Try
Don't!
inline string trim_right(const string& source, const string& t = " "){
string str = source;
return str.erase(source.find_last_not_of(t) + 1);}
1. You search only for " ", not for white space (e.g. '\t')
2. find_last_not_of() returns npos when no match is found (which is not an appropriate input for erase)
3. You return by value thus duplicating the string unnecessarily.
In sum, your 'solution' is incorrect and inefficient, but fine otherwise.
|
|
|
|
|
I copied the code from somewhere. It seemed to work for me so I didn't check its details. Still, I think a trim function should have been part of basic_string (if only to prevent incorrect implementations like this! ). It's a common enough operation.
Kevin
|
|
|
|
|
|
Sloppy Joseph wrote:
You search only for " ", not for white space (e.g. '\t')
Actually it does handle '\t', as I've only specified a default argument.
Sloppy Joseph wrote:
find_last_not_of() returns npos when no match is found (which is not an appropriate input for erase)
Agreed, but still seems to work anyway.
Sloppy Joseph wrote:
You return by value thus duplicating the string unnecessarily.
OK, how about this?
inline string& trim(string& s, const string& t)
{
string::size_type st1, st2;
st1 = s.find_first_not_of(t);
if (st1 != string::npos)
{
st2 = s.find_last_not_of(t) + 1;
s = s.substr(st1, st2 - st1);
}
else
{
s.clear();
}
return s;
}
Kevin
|
|
|
|
|
Kevin McFarlane wrote:
Actually it does handle '\t', as I've only specified a default argument.
Well, you require the user to define the white spaces for you? This is, at least, not user friendly (answer quickly, which chars are white space? Is '\n' a white space, is '\a'?). Hint: isspace.
Agreed, but still seems to work anyway.
An questionable answer for a professional software developer.
OK, how about this?
if (st1 != string::npos)
{
st2 = s.find_last_not_of(t) + 1;
s = s.substr(st1, st2 - st1);
}
substr() produces a (partial) copy which is assigned (= copied again) to s. You can do it all in place.
|
|
|
|
|
|
Hi,
I want to pass the pointer held by an auto_ptr as a reference to a function. Is it possible?. I give an example below,
#include<iostream>
using namespace std;
void fn(int *ptr);
int main()
{
std::auto_ptr<int> a(new int(11));
fn(a.get());
cout<<"\na"<<*a;
return 0;
}
void fn(int* &ptr)
{
}
I am getting a compilation error
Undefined first referenced
symbol in file
void fn(int*) stdauto1.o
ld: fatal: Symbol referencing errors. No output written to a.out
Any answers?
Thanks,
kramkrish
|
|
|
|
|
Try
void fn(int* ptr)
{
(*ptr)++;
}
int _tmain(int argc, _TCHAR* argv[])
{
std::auto_ptr<int> a(new int(11));
fn(a.get());
cout << "a = " << *a << endl;
return 0;
}
|
|
|
|
|
If you really need to pass a reference to the pointer, try :-
void fn(int*& ptr)
{
}
int _tmain(int argc, _TCHAR* argv[])
{
std::auto_ptr<int> a(new int(11));
int* tmp;
fn(tmp = a.get());
return 0;
}
|
|
|
|
|
Hi,
Sorry for the trouble. I think I did a very basic mistake (ashamed of myself ),
In the function declaration, I didnt mention the reference. When I give the reference its working fine.
Thanks for your suggestion,
kramkrish
|
|
|
|
|
I suppose a const pointer ref would do...?
Good music: In my rosary[^]
|
|
|
|
|
Jörgen Sigvardsson wrote:
I suppose a const pointer ref would do...?
Yes, but since he wants to pass the pointer by reference, I suppose it's because he wants to change the pointer, so a const pointer would not really serve his requirement.
Nish
|
|
|
|
|
Hi Folks,
I am using Microsoft Visual Studio .NET 2003 (Visual C++ 7.1) to access a webservice.
Scenario is:
I make a call to one of the methods of webservice. The call goes succesfully through the webservice. However, it fails while reading the response back from the webservice.
This happens for a specific case if the chunk size is 07ff or 0800 bytes. Here, chunk size is the size of the SOAP response (it does not include HTTP header & footer size). Technically it is the value calculated as nChunkSize on line 1818 in atlhttp.inl.
The code line is:
cresult = get_chunked_size(chunk_buffer, chunk_buffer_end, &nChunkSize);
The call fails because a value of LEX_ERROR is set by the "consume_chunk_footer" function of atlhttp.inl. It seems to me that in this particular case, the socket reads 1 byte less than the actual no. of bytes to be read, and so, it does not find the character '\n' which makes this function to return LEX_ERROR instead of LEX_OK.
I have tested this taking various data. But it fails only for the above scenario.
This seems to be a definite BUG. However, I am not sure if the patch already exists for it. If someone has any workarounds, do let me know.
Regards,
Arun Gupta.
|
|
|
|
|
Hello Folks!
I'm trying to build a DCOM server that interfaces a foreign API (National Instruments IMAQ Vision, for precision).
I implemented my ATL object, created interface, and added methods.... some of them use, in parameters, native types defined in the API library (I got a LIB + 1 .H files), so I wrote, at the beginning of my IDL file:
import "nivision.h";
and continued adding methods.
When I compiled, I got MIDL errors indicating redefinitions on 80% of typedefs in .H file.
What's wrong? Me, probably?
I can post or send code, if needed.
Thanks in advance,
Morenz
|
|
|
|
|
Yep, it was me, in part
The other part goes to National Instruments, which header file I had to modify by 80%, commenting out redefinitions (they referred 'em as "forward delarations"... in fact in an MFC app worked well, but MIDL compiler was not so happy...
Now I'm trying to obtain from NI a "simpler" way to make an ATL server with their types without destroying their headers....
Bye
Morenz
|
|
|
|
|
please help me..
I've developed something.
First I made a txt file that contains just some word "Hello, Bye, etc.." and then load it on the IE.
Second check the text on the IE, and then compare the text with some pattern like "Hello".
Third I add some html cord. The function of cord would change background color of the text "Hello" and hand cursor shape, if the pattern is same.
OK. Now I want to add some more function.
1. If I click the text that was already changed background color, and some more things,
('couse same with some pattern like "Hello")
then I want to make pop up my Dialog box(modal) on the IE. The box name is IDD_POPUP.
2. Next, the IDD_POPUP has a static text. I want to show the "Hello" on the static box of IDD_POPUP.
That's all.. plz help me~
------------------------------------------------------------------------------------------------
void CABC::RegexHighlight(CComPtr spHTML)
///reference - http://www.codeproject.com/miscctrl/chtmlview_search.asp
{
static IRegExpPtr regExp( __uuidof(RegExp) );
static IRegExpPtr regExp_1( __uuidof(RegExp) );
LPCTSTR lpszPattern = " Hello /*some pattern*/ ";
regExp->Pattern = lpszPattern;
regExp->put_Global(VARIANT_TRUE);
IMatchCollectionPtr matches;
IMatchPtr match, tempMatch;
long m_cnt;
int i;
long startPoint, strLength;
IHTMLElement *lpBodyElm;
IHTMLBodyElement *lpBody;
IHTMLTxtRange *lpTxtRange;
bool bFound;
spHTML->get_body(&lpBodyElm);
lpBodyElm->QueryInterface(IID_IHTMLBodyElement,(void**)&lpBody);
lpBody->createTextRange(&lpTxtRange);
CString cstr;
BSTR bstr, tmpbstr;
BSTR bmark;
VARIANT_BOOL ret;
lpTxtRange->get_text(&bstr);
lpTxtRange->getBookmark(&bmark);
cstr = bstr;
matches = regExp->Execute(bstr);
m_cnt = matches->Count;
CString chkStr[1000];
long c_cnt = 0;
bool isChk = false;
for (i = 0; i < m_cnt; i++) {
match = matches->Item[i];
startPoint = match->FirstIndex;
strLength = match->Length;
match->get_Value(&tmpbstr);
CString searchText = tmpbstr;
CComBSTR html;
CComBSTR newhtml;
CComBSTR search(searchText.GetLength()+1,(LPCTSTR)searchText);
while(lpTxtRange->findText(search,0,2,(VARIANT_BOOL*)&bFound),bFound) //lFlags = 2 or 0
{
newhtml.Empty();
lpTxtRange->get_htmlText(&html);
//change the background color, etc..
newhtml.Append(" <span id='regexnum' style='color: Black; background-color: yellow'><font style='cursor:hand'>");
newhtml.AppendBSTR(html);
newhtml.Append("dssd");
lpTxtRange->pasteHTML(newhtml);
}
lpTxtRange->moveToBookmark(bmark, &ret);
}
}
|
|
|
|
|
Sorry I couldn't reply sooner ... since you've indicated you've been reading the Programming IE 5 book, that will save a bunch of your time and my typing.
Check out the section called Sinking Events for DHTML Objects in Visual C++. There's an entire code block provided that shows how you can catch click events and handle them (in this case, a double click). Not exactly certain how you can determine what text was clicked ... I didn't sit and read the entire chp. on the subject; but their ATL Browser example has a good bit of C++ good for you to look over.
You could always make that text item an HTML anchor with a bogus URL and then in the OnBeforeNavigate method, check in the incoming URL to see if they match (then you know what item was clicked upon) ...
Obviously if you don't want the text to look like a standard Hyperlink, you'll have to change that through a style sheet or whatnot ...
:..::. Douglas H. Troy ::..
Fold with us|Development Blogging|viksoe.dk's site
|
|
|
|
|
Thank you~
Your answer help me definitly.
Actually I didn't know whick section is fit for me.
So I've just trying to read the entire book.
Today I'll try to understand the section "Sinking Events for DHTML Objects in Visual C++" and more section.
Thanx
|
|
|
|
|