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...)
--
Christopher Benson-Manica | Jumonji giri, for honour.
ataru(at)cyberspace.org | 32 8801
<at***@nospam.cyberspace.org> wrote in message news:bi**********@chessie.cirr.com... 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[i] = 'e';
Ron Natalie <ro*@sensor.com> broke the eternal silence and spoke thus: Actually, for a single character this would be just as good s[i] = 'e';
You can reference strings as though they were C-style char*'s?
--
Christopher Benson-Manica | Jumonji giri, for honour.
ataru(at)cyberspace.org | at***@nospam.cyberspace.org: 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
<at***@nospam.cyberspace.org> wrote in message
news:bi**********@chessie.cirr.com... Ron Natalie <ro*@sensor.com> broke the eternal silence and spoke thus:
Actually, for a single character this would be just as good s[i] = '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
Agent Mulder <mb*******************@home.nl> wrote in message
news:bi**********@news2.tilbu1.nb.home.nl... at***@nospam.cyberspace.org: 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');
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::operator[]()'.
$.02,
-Mike
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[i] = 'e';
std::cout << s << '\n';
return 0;
}
</mikes>
-X
<at***@nospam.cyberspace.org> wrote in message news:bi**********@chessie.cirr.com... Ron Natalie <ro*@sensor.com> broke the eternal silence and spoke thus:
Actually, for a single character this would be just as good s[i] = 'e';
You can reference strings as though they were C-style char*'s?
Well, not totally, but they do support operator[] as shown above.
Mike Wahler <mk******@mkwahler.net> broke the eternal silence and spoke thus: 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?
--
Christopher Benson-Manica | Jumonji giri, for honour.
ataru(at)cyberspace.org |
Mike Wahler <mk******@mkwahler.net> broke the eternal silence and spoke thus: 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?
--
Christopher Benson-Manica | Jumonji giri, for honour.
ataru(at)cyberspace.org |
"Mike Wahler" <mk******@mkwahler.net> wrote in message
news:l8*****************@newsread4.news.pas.earthl ink.net... Agent Mulder <mb*******************@home.nl> wrote in message news:bi**********@news2.tilbu1.nb.home.nl... at***@nospam.cyberspace.org: 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');
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::operator[]()'.
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.
Agent Mulder <mb*******************@home.nl> wrote in message
news:bi**********@news2.tilbu1.nb.home.nl... 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
Bob Jacobs <ne****@robertjacobs.fsnet.co.uk> broke the eternal silence and spoke thus: 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.
--
Christopher Benson-Manica | Jumonji giri, for honour.
ataru(at)cyberspace.org |
<at***@nospam.cyberspace.org> wrote in message
news:bi**********@chessie.cirr.com... Mike Wahler <mk******@mkwahler.net> broke the eternal silence and spoke
thus: 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?
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 -- Christopher Benson-Manica | Jumonji giri, for honour. ataru(at)cyberspace.org |
"Mike Wahler" <mk******@mkwahler.net> wrote in message news:Tu81b.1985 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.
<at***@nospam.cyberspace.org> wrote in message news:bi**********@chessie.cirr.com... Bob Jacobs <ne****@robertjacobs.fsnet.co.uk> broke the eternal silence and spoke thus:
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.
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.
Mike Wahler <mk******@mkwahler.net> broke the eternal silence and spoke thus: 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()?
--
Christopher Benson-Manica | Jumonji giri, for honour.
ataru(at)cyberspace.org |
Mike Wahler <mk******@mkwahler.net> broke the eternal silence and spoke thus: 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?
--
Christopher Benson-Manica | Jumonji giri, for honour.
ataru(at)cyberspace.org |
<at***@nospam.cyberspace.org> wrote in message news:bi**********@chessie.cirr.com... Mike Wahler <mk******@mkwahler.net> broke the eternal silence and spoke thus:
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()?
You can write one in a few lines. strtok bites because it maintains a
hidden internal state and that it modifies it's input. at***@nospam.cyberspace.org wrote: Ron Natalie <ro*@sensor.com> broke the eternal silence and spoke thus:
Actually, for a single character this would be just as good s[i] = 'e';
You can reference strings as though they were C-style char*'s?
Yes. What book are you using?
Brian Rodenborn
Ron Natalie wrote: <at***@nospam.cyberspace.org> wrote in message news:bi**********@chessie.cirr.com...
Mike Wahler <mk******@mkwahler.net> broke the eternal silence and spoke thus: I guess I'm still dwelling in pointer-land... oh well. Actually, did C++ come up with a better strtok()?
You can write one in a few lines. strtok bites because it maintains a hidden internal state and that it modifies it's input.
IANALG (I am not a language guru), but I'd bet that your best bet is to write a
"Tokenizer" class. The advantage of that over "strtok" would be that (if done right)
each Tokenizer would have its own state, so you could have several different "parsings"
going on simultaneously, plus you wouldn't corrupt your original string.
AM> You produced some very ugly code, Mike ;-)7
MW> Why do you find it 'ugly'? What would you do instead
MW> that you'd consider less 'ugly'?
At least you took the effort to type code. That's good.
#include <iostream>
#include <algorithm>
#include <string>
int main(int argc,char**argv)
{
std::string s("Bach");
std::cout<<"\nBefore: "<<s.c_str();
std::replace(s.begin(),s.end(),'B','J');
std::replace(s.begin(),s.end(),'c','h');
std::replace(s.begin(),s.end(),'h','z');
std::cout<<"\nAfter: "<<s.c_str();
}
______
output
Before: Bach
After: Jazz
<at***@nospam.cyberspace.org> wrote in message
news:bi**********@chessie.cirr.com... Ron Natalie <ro*@sensor.com> broke the eternal silence and spoke thus:
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. I know this now, which is why I said my original plan was flawed (because
I *did* want to shorten the string...) :)
#include <iostream>
#include <string>
int main()
{
std::string s("blah");
std::string::size_type pos(s.find('a'));
if(pos != std::string::npos)
s.erase(pos);
std::cout << s << '\n'; /* prints "bl" */
return 0;
}
Recommendation: http://www.josuttis.com/libbook/index.html
-Mike
"red floyd" <no*****@here.dude> wrote in message news:G9*******************@newssvr21.news.prodigy. com... IANALG (I am not a language guru), but I'd bet that your best bet is to write a "Tokenizer" class. The advantage of that over "strtok" would be that (if done right) each Tokenizer would have its own state, so you could have several different "parsings" going on simultaneously, plus you wouldn't corrupt your original string.
Yep, and I believe if you google back a bit in this group for "stringtok" you'll find one has
been posted. at***@nospam.cyberspace.org wrote: Ron Natalie <ro*@sensor.com> broke the eternal silence and spoke thus:
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.
I know this now, which is why I said my original plan was flawed (because I *did* want to shorten the string...) :)
If you want to use std::string, you need to sit and study them
thoroughly. Stop worrying about C-style strings.
Brian Rodenborn
Agent Mulder <mb*******************@home.nl> wrote in message
news:bi**********@news2.tilbu1.nb.home.nl... AM> You produced some very ugly code, Mike ;-)7
MW> Why do you find it 'ugly'? What would you do instead MW> that you'd consider less 'ugly'?
At least you took the effort to type code. That's good.
#include <iostream> #include <algorithm> #include <string> int main(int argc,char**argv) { std::string s("Bach"); std::cout<<"\nBefore: "<<s.c_str(); std::replace(s.begin(),s.end(),'B','J'); std::replace(s.begin(),s.end(),'c','h'); std::replace(s.begin(),s.end(),'h','z'); std::cout<<"\nAfter: "<<s.c_str(); }
Why is my code 'uglier' than yours?
I find yours 'uglier' if for no other reason than
that you failed to indent. You also declared parameters
to main() which you never use. Yuck! :-)
Why do you make the unnecessary call to 'c_str()'
for output?
(My computer can beat up your computer! :-) )
-Mike at***@nospam.cyberspace.org wrote: Mike Wahler <mk******@mkwahler.net> broke the eternal silence and spoke thus:
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()?
Nothing built-in. Here's a utility I wrote, it's not equivilent to
strtok() but rather ones like PHP explode():
#include <vector>
#include <string>
// breaks apart a string into substrings separated by a character string
// does not use a strtok() style list of separator characters
// returns a vector of std::strings
std::vector<std::string> Explode (const std::string &inString,
const std::string &separator)
{
std::vector<std::string> returnVector;
std::string::size_type start = 0;
std::string::size_type end = 0;
while ((end=inString.find (separator, start)) != std::string::npos)
{
returnVector.push_back (inString.substr (start, end-start));
start = end+separator.size();
}
returnVector.push_back (inString.substr (start));
return returnVector;
}
Brian Rodenborn
Default User <fi********@company.com> wrote in message
news:3F***************@company.com... at***@nospam.cyberspace.org wrote: Mike Wahler <mk******@mkwahler.net> broke the eternal silence and spoke
thus: 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()?
Nothing built-in. Here's a utility I wrote, it's not equivilent to strtok() but rather ones like PHP explode():
#include <vector> #include <string>
// breaks apart a string into substrings separated by a character string // does not use a strtok() style list of separator characters // returns a vector of std::strings
std::vector<std::string> Explode (const std::string &inString, const std::string &separator) { std::vector<std::string> returnVector; std::string::size_type start = 0; std::string::size_type end = 0;
while ((end=inString.find (separator, start)) != std::string::npos) { returnVector.push_back (inString.substr (start, end-start)); start = end+separator.size(); }
returnVector.push_back (inString.substr (start));
return returnVector; }
I guess I'll throw mine away now. :-) I started to
hack one out, which was beginning to look very much
like this. :-)
Thanks.
-Mike
Duh, I forgot the return statement:
#include <string>
#include <iostream>
#include <algorithm>
static std::string s="Bach";
int main(int argc,char**argv)
{
std::cout<<"\nBefore: "<<s.c_str();
std::replace(s.begin(),s.end(),'B','J');
std::replace(s.begin(),s.end(),'c','h');
std::replace(s.begin(),s.end(),'h','z');
std::cout<<"\nAfter: "<<s.c_str();
return 0;
}
______
output
Before: Bach
After: Jazz at***@nospam.cyberspace.org wrote: Default User <fi********@company.com> broke the eternal silence and spoke thus:
Nothing built-in. Here's a utility I wrote, it's not equivilent to strtok() but rather ones like PHP explode():
Explode? Oh, you mean like "get bigger" and not "make pretty exceptions all over the place" ;)
Like bust it into pieces.
Brian Rodenborn
Mike Wahler wrote: I guess I'll throw mine away now. :-) I started to hack one out, which was beginning to look very much like this. :-)
I had a project last year that required parsing long strings (flight
plans) with nested delimiters, first "\r\n", then "..", then ":",
finally ",".
Brian Rodenborn at***@nospam.cyberspace.org wrote: Default User <fi********@company.com> broke the eternal silence and spoke thus:
Nothing built-in. Here's a utility I wrote, it's not equivilent to strtok() but rather ones like PHP explode():
Explode? Oh, you mean like "get bigger" and not "make pretty exceptions all over the place" ;)
(code)
Cool, thank you...
One major difference between that code and strtok() (besides string
separators vs. character delimiters) is the behavior with adjacent
delimiters.
Example, the string "one,two,,three" gives the tokens:
one
two
three
When using strtok().
And:
one
two
three
With the Explode() routine. That's by design and desire, so that "empty"
fields are represented, not just ignored.
Brian Rodenborn This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Venkat |
last post by:
Hi All,
I need to copy strings from a single dimensional array to a double
dimensional array.
Here is my program.
#include <stdio.h>
#include <stdlib.h>
|
by: stroker_ace |
last post by:
Hi,
I wonder if anyone could point me in the direction of a discussion on
the similarities and differences between the C++ String type and char*
strings?
The reason I ask is because I am...
|
by: Il Prof |
last post by:
Hi!
I'm new in C language (but not in structured programming) and i have
some questions about strings:
1) What of this two string access methods is faster?
- Direct access of the elemtns of...
|
by: David Jacques |
last post by:
I have to reformat a string from the form
"SRID=4269;POINT(-90.673 69.4310000006199)"
to
GeometryFromText('POINT (-141.095 68.5430000006417)',4269) );
I have a function to do this by...
|
by: I. Myself |
last post by:
This is about reading the .ini files which are used in several of our
projects.
Currently, the actual read of each line of the file is with this statement:
fscanf(file, "%s %s", name, value);...
|
by: pkirk25 |
last post by:
I wonder if anyone has time to write a small example program based on
this data or to critique my own effort?
A file called Realm List.html contains the following data:
Bladefist-Horde...
|
by: cman |
last post by:
Can you "walk across" C strings or char pointers (using *(sz+1)) like
you can with arrays. If not, why not? If so, how?
cman
|
by: ts |
last post by:
Hello all,
Can somebody explain why strchr is declared the way it is? Here is
the declaration:
char *strchr(const char *s, int c);
Mainly I do not understand why the second ...
|
by: hstagni |
last post by:
Where can I find a library to created text-based windows applications?
Im looking for a library that can make windows and buttons inside
console.. Many old apps were make like this, i guess
...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
| |