C++ strings and strchr()

A

ataru

I want to find the position of a character in a string and replace it another
if it is actually there, and I'd like the operation to be efficient. I'm
assuming the "standard" way to do this is something like

string s = "blah";
int i = s.find_first_of('a'); /* returns 2, I presume? */
s.replace(i,0,"e");

Right? Is this the best way (assuming I haven't made some stupid error)? Is
there a way to (easily!) get a character pointer from a C++ string so I can
just change that one character, like maybe

char *cp;

if( (cp=strchr(s.c_str(), 'a') != NULL)
*cp='e';

? If neither way is good, what's a better way?

(if this is a FAQ, I didn't see it...)
 
R

Ron Natalie

string s = "blah";
int i = s.find_first_of('a'); /* returns 2, I presume? */

You need to check to see if the find succeeds (unless you are sure it won't fail).
It might return npos. You could also use s.find('a'). Since your match string is
only a single character they both do the same thing (I'm not sure that one would
be faster than the other).
s.replace(i,0,"e");

That's a no op. It says to replace zero chars. You want.
s.replace(i, 1, "e");
Actually, for a single character this would be just as good
s = 'e';
 
A

Agent Mulder

(e-mail address removed):
I want to find the position of a character in a string and replace it another
if it is actually there, and I'd like the operation to be efficient. I'm
assuming the "standard" way to do this is something like

string s = "blah";
int i = s.find_first_of('a'); /* returns 2, I presume? */
s.replace(i,0,"e");

#include<algorithm>
replace(s.begin(),s.end(),'a','e');

-X
 
M

Mike Wahler

Ron Natalie said:
Actually, for a single character this would be just as good
s = 'e';


You can reference strings as though they were C-style char*'s?


Not entirely. E.g. 'strlen()' et al won't necessarily work
as you expect. But std::string does feature 'index'
operators '[]'. It also has other 'intuitive' operators,
such as '+' for concatenation.

Which C++ book(s) are you reading?

-Mike
 
M

Mike Wahler

Agent Mulder said:
(e-mail address removed):

#include<algorithm>
replace(s.begin(),s.end(),'a','e');

Nearly all C++ literature I've read states that one
should usually prefer a member function over a 'free'
function, if it does what you need. This is because
a member function could be optimized to take advantage
of internal details not available to 'free' functions.

In OP's case, I'd use 'std::string::find()' followed
by access to the found element with 'std::string::eek:perator[]()'.

$.02,
-Mike
 
A

ataru

Mike Wahler said:
Which C++ book(s) are you reading?

"The C++ Programming Language" by Stroustrup (aka God?) - it's in there, but
the book is so big I overlooked it... sorry... but I do have a question
about how they're implemented. Why can't you effectively modify the char*
that c_str gives you? Wouldn't that make one's life easier?
 
A

Agent Mulder

MW> Nearly all C++ literature I've read states that one
MW> should usually prefer a member function over a 'free'
MW> function, if it does what you need. This is because
MW> a member function could be optimized to take advantage
MW> of internal details not available to 'free' functions.

You produced some very ugly code, Mike ;-)7

<mikes>
#include <iostream>
#include <string>

int main()
{
his();
std::string s("blah");
std::cout << s << '\n';
std::string::size_type i(s.find('a'));

if(i != std::string::npos)
s = 'e';

std::cout << s << '\n';

return 0;
}
</mikes>

-X
 
A

ataru

Mike Wahler said:
Which C++ book(s) are you reading?

"The C++ Programming Language" by Stroustrup (aka God?) - it's in there, but
the book is so big I overlooked it... sorry... but I do have a question
about how they're implemented. Why can't you effectively modify the char*
that c_str gives you? Wouldn't that make one's life easier when dealing with
C-style string functions?
 
B

Bob Jacobs

Mike Wahler said:
Agent Mulder said:
(e-mail address removed):

#include<algorithm>
replace(s.begin(),s.end(),'a','e');

Nearly all C++ literature I've read states that one
should usually prefer a member function over a 'free'
function, if it does what you need. This is because
a member function could be optimized to take advantage
of internal details not available to 'free' functions.

In OP's case, I'd use 'std::string::find()' followed
by access to the found element with 'std::string::eek:perator[]()'.

It would be useful to know the OP's intention here, as the two examples
aren't completely equivalent. One is intended to replace the first occurence
of 'a' with 'e' whilst the other will replace all instances of 'a' with 'e'.
For "blah" the effect is the same, of course.
 
M

Mike Wahler

Agent Mulder said:
MW> Nearly all C++ literature I've read states that one
MW> should usually prefer a member function over a 'free'
MW> function, if it does what you need. This is because
MW> a member function could be optimized to take advantage
MW> of internal details not available to 'free' functions.

You produced some very ugly code, Mike ;-)7

Why do you find it 'ugly'? What would you do instead
that you'd consider less 'ugly'?

-Mike
 
A

ataru

Bob Jacobs said:
It would be useful to know the OP's intention here, as the two examples
aren't completely equivalent. One is intended to replace the first occurence
of 'a' with 'e' whilst the other will replace all instances of 'a' with 'e'.
For "blah" the effect is the same, of course.

My original (flawed!) intention was actually to replace a single character in
a string with a null terminator (a la C - guess what I took in college? ;)),
which of course wouldn't have worked... And then I realized that the strings
I wanted already existed in the code anyway, so the whole exercise was
pointless... but at least I learned something.
 
M

Mike Wahler

Mike Wahler <[email protected]> broke the eternal silence and spoke thus:

"The C++ Programming Language" by Stroustrup (aka God?) - it's in there, but
the book is so big I overlooked it... sorry... but I do have a question
about how they're implemented. Why can't you effectively modify the char*
that c_str gives you? Wouldn't that make one's life easier when dealing with
C-style string functions?

Why do you want to use those functions with std::string's?

AFAIK, std::string supports anything you can do with a 'C-style
string', and more, in a much safer way.

-Mike
 
T

Thomas Matthews

Actually, for a single character this would be just as good
s = 'e';



You can reference strings as though they were C-style char*'s?


You can't access the string directly as C-style char*'s,
but you _can_ access a copy that is a C-style string.
Look up the "c_str()" method:
string b("blah");
cout << strlen(b.c_str());

The std::string class has many of the functions that
are used on C-style strings. Look through the list
of std::string methods.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
 
R

Ron Natalie

Mike Wahler said:
2) Even if modifying this array were allowed, it is *not*
the characters of the string itself, only a copy.

Well, potentially not. In practice, it usually is.
 
R

Ron Natalie

My original (flawed!) intention was actually to replace a single character in
a string with a null terminator (a la C - guess what I took in college? ;)),
which of course wouldn't have worked... And then I realized that the strings
I wanted already existed in the code anyway, so the whole exercise was
pointless... but at least I learned something.

Did you really want to poke a null terminator there, or shorten the string.
Putting a null terminator in a C++ string doesn't make it any shorter.
 
A

ataru

Mike Wahler said:
AFAIK, std::string supports anything you can do with a 'C-style
string', and more, in a much safer way.

I guess I'm still dwelling in pointer-land... oh well. Actually, did C++
come up with a better strtok()?
 
A

ataru

Mike Wahler said:
1) c_str() returns a pointer to an array of *const* characters.
2) Even if modifying this array were allowed, it is *not*
the characters of the string itself, only a copy.

Yes, but my question is why? Are they that afraid of someone actually getting
a char* with strchr() or something and modifying it? Or is it just to
discourage C-style thinking?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top