dealing with stringstream in C++ - c++

i am reverting back to cpp after long years i have not been using it at all. i am trying to stay up date whilst refreshing my memories with correct practices and syntax, so i prefer the answers to be leaned towards cpp 17 onward(though 20 is not out yet).
so my situation is like this, assuming i have a stringstream object, i want to find an efficient way to convert its contents into upper/lower case. then i'll play with it(each even char in the string, etc). however, as far as i remember, unlike other programming languages, in c++ ::toupper/lower is done on chars, so i think it means i need to use std::transform on this container.
if you could regard the following questions while answering it would be great and allow me to capture multiple birds with one net, or something like this:
is it possible to do this with a for_each?
is it possible to use string_view and then refer to it to do the operations on it if i don't want to create a new string object to do the case manipulation?
are there any iterators for stringstream object? (like begin(),end() etc)
so what's the best way to do implement case change here?
is it possible to do this somehow without converting this to string, but rather manipulating it manually or is it path for trouble?
here's what i tried and failed ungracefuly with:
int main() {
std::stringstream beginnersmistake;
beginnersmistake<<"learning"<< " " << "to"<< "program" <<'\n';
std::function<std::stringstream> ttoupper = [&beginnersmistake](){
std::string stemp = beginnersmistake.str();
std::transform(stemp.begin(),stemp.end(),stemp.begin(),::toupper);
};
std::cout<<"voila! a mistake comming:" << ttoupper;
beginnersmistake.clear();
getchar();
return 0;
}
thank you very much for helping a noobie joining the site :)

Related

Efficient way to check if string contains value of vector<string>?

I'm pretty new to C++ programming but for certain reasons I need to develop a small tool in C++. I've written the same tool in C# already. Right now I'm trying to check if my string contains a value that is stored in a std::vector. In C# this is pretty straight forward, simply using something like this:
if(string.Contains(myarray)) { // do sth. }
In C++ this seems way harder to achieve. I googled quite a bit but so far I found only solutions to check if the WHOLE string exists in an array and not just a certain part of it.
Unfortunately std::string does not have a method that can see if a element of a vector is in a string like C# does. What it does have though is std::string::find which can determine if a string is contained within the string you call find on. You could use that like
std::vector<std::string> words;
// fill words
std::string search_me = "some text";
for (const auto & e : words)
{
if (search_me.find(e) != std::string::npos)
{
// e is contained in search me. do something here
// call break here if you only want to check for one existence
}
}
This is O(N*complexity_of_find).
Use a for loop and the find method.
I would suggest std::find_first_of
Not sure if I understood your exact problem, though. Could you give a small example of what your are trying to find in what?
If you need more effective way to find several substrings in string than straightforward find string-by-string, you can use Aho-Corasick algorithm
It uses trie to hold substrings. First google link to c++ implementation

Is there method of in place string manipulation native to the mingw libraries that doesn't involve i/o streams

I am attempting to construct a serial number of a certain format. This number will be entered into a database. At this point I am having to use sprintf, but I would like a native C++ method for it.
Here is sample code:
int i;
sprintf(buffer, "%03d", i);
The integer will be anywhere from 1 to 3 digits. The format needs to look like this:
001, ... 013, ... 101, ... etc.
The "serial number" has the format:
AAAAA001, ... AAAAA013, ... AAAAA101, etc.
So the question is, is there a way to do this that is native to C++ without having to use iostream manipulators and that is included in the mingw-w64 libraries. Or does it require something like boost libraries?
Another way to put it: is there a drop-in replacement in C++ for the C sprintf function?
Edit based upon comments:
So there is nothing as simple as....
int i;
string buffer;
sprintf(buffer, "%03d", i);
I realize that this does not work, but it gives the thought anyway. There is no way to operate directly on a string class object with a method that serves the function of sprintf?
I'm taking aruisdante's answer as the best answer to the question although it is a stream which I initially found undesirable.
I think the real question you have to answer first is "why do you not want >to use sstream "? Without establishing that first, it's a bit of an >XYProblem, since sstream will certainly solve the given problem clearly, >type-safely and relatively efficiently. – aruisdante
My understanding of streams was too narrow. It looks like a stringstream should work well for my application.
Thanks again.

When to use std::string vs char*? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++ char* vs std::string
I'm new to C++ coming from C# but I really do like C++ much better.
I have an abstract class that defines two constant strings (not static). And I wondered if a const char* would be a better choice. I'm still getting the hang of the C++ standards, but I just figured that there really isn't any reason why I would need to use std::string in this particular case (no appending or editing the string, just writing to the console via printf).
Should I stick to std::string in every case?
Should I stick to std::string in every case?
Yes.
Except perhaps for a few edge cases where you writing a high performance multi-threaded logging lib and you really need to know when a memory allocation is going to take place, or perhaps in fiddling with individual bits in a packet header in some low level protocol/driver.
The problem is that you start with a simple char and then you need to print it, so you use printf(), then perhaps a sprintf() to parse it because std::stream would be a pain for just one int to string. And you end up with an unsafe and unmaintainable mix oc c/c++
I would stick to using std::string instead of const char*, simply because most of the built-in C++ libraries work with strings and not character arrays. std::string has a lot of built-in methods and facilities that give the programmer a lot of power when manipulating strings.
Should I stick to std::string in every case?
There are cases where std::string isn't needed and just a plain char const* will do. However you do get other functionality besides manipulation, you also get to do comparison with other strings and char arrays, and all the standard algorithms to operate on them.
I would say go with std::string by default (for members and variables), and then only change if you happen to see that is the cause of a performance drop (which it won't).
Use std::string when you need to store a value.
Use const char * when you want maximum flexibility, as almost everything can be easily converted to or from one.
This like comparing Apples to Oranges. std::string is a container class while char* is just a pointer to a character sequence.
It really all depends on what you want to do with the string.
Std::string on the other hand can give you a quick access for simple string calculation and manipulation function. Most of those are simple string manipulation functions, nothing fancy really.
So it basically depends on your needs and how your functions are declared. The only advantage for std::string over a char pointer is that it doesnt require a specific lenghth decleration.

I'm getting contradictory answers, what should I do with my code?

I am making a RPG game in C++ and DirectX.
I store all the data for the game in .txt files and read/write it using `ifstream/ofstream. this has worked well for me so far when talking about creature stats and I have a hack together for creature names but this is becoming a problem.
I can store strings in the txt file and read them but I am having trouble using them. for single words I have a hack but now I am up to the story line where characters are talking to each other it is a real problem.
I asked on gamedevelopment.stackexchange how to put text on screen and was told to use D3Dtext but that only accepts C-style strings and I can only read C++ strings from the text file. This is such a big problem now that I am willing to go back and re-factor what need sit as no progress can be made until this is sorted.
So now I have a bunch of questions and I dont know which to ask first:
I want a way to draw the letters like graphics. I was told this is what D3Dtext does but I want to implement it my self if I can I just need info on how if someone knows?
If I am to use D3Dtext like so called experts advise I have to use C-style strings. so how can I convert C-style strings to C++ strings? I have a method now but that requires the new and delete operator for every string and I can see the being a big problem as it grows in complexity?
Is there a way to read C-style strings? Maybe a replacement for ifstream. I would like to keep the txt files as I really dont want to use xml but I could change the file format if it was a viable solution?
Premature optimisation I know but I plan to use the same function for every piece of text in the game so what would be a good way of doing this in terms of speed (why I dont want new/delete for every string)?
I am happy to provide any information that would be needed to help me, just ask.
std::string mystr = "Hello World.";
mystr.c_str(); // gets a null terminated const char* C-style string
Read your file as you are currently doing then if you need to access the c strings as above.
You can convert freely between C-style strings and C++'s std::string. Just use my_cpp_string.c_str() to get the C-string representation of a C++ string, and std::string my_cpp_string(my_c_string) to initialize a new std::string from a C-style string.
2) Use the c_str() method to pass your C++ strings to D3Dtext
some_D3Dtext_function(some_text.c_str())
3 and 4 then become non-issues.

What's the difference between istringstream, ostringstream and stringstream? / Why not use stringstream in every case?

When would I use std::istringstream, std::ostringstream and std::stringstream and why shouldn't I just use std::stringstream in every scenario (are there any runtime performance issues?).
Lastly, is there anything bad about this (instead of using a stream at all):
std::string stHehe("Hello ");
stHehe += "stackoverflow.com";
stHehe += "!";
Personally, I find it very rare that I want to perform streaming into and out of the same string stream.
Usually I want to either initialize a stream from a string and then parse it; or stream things to a string stream and then extract the result and store it.
If you're streaming to and from the same stream, you have to be very careful with the stream state and stream positions.
Using 'just' istringstream or ostringstream better expresses your intent and gives you some checking against silly mistakes such as accidental use of << vs >>.
There might be some performance improvement but I wouldn't be looking at that first.
There's nothing wrong with what you've written. If you find it doesn't perform well enough, then you could profile other approaches, otherwise stick with what's clearest. Personally, I'd just go for:
std::string stHehe( "Hello stackoverflow.com!" );
A stringstream is somewhat larger, and might have slightly lower performance -- multiple inheritance can require an adjustment to the vtable pointer. The main difference is (at least in theory) better expressing your intent, and preventing you from accidentally using >> where you intended << (or vice versa). OTOH, the difference is sufficiently small that especially for quick bits of demonstration code and such, I'm lazy and just use stringstream. I can't quite remember the last time I accidentally used << when I intended >>, so to me that bit of safety seems mostly theoretical (especially since if you do make such a mistake, it'll almost always be really obvious almost immediately).
Nothing at all wrong with just using a string, as long as it accomplishes what you want. If you're just putting strings together, it's easy and works fine. If you want to format other kinds of data though, a stringstream will support that, and a string mostly won't.
In most cases, you won't find yourself needing both input and output on the same stringstream, so using std::ostringstream and std::istringstream explicitly makes your intention clear. It also prevents you from accidentally typing the wrong operator (<< vs >>).
When you need to do both operations on the same stream you would obviously use the general purpose version.
Performance issues would be the least of your concerns here, clarity is the main advantage.
Finally there's nothing wrong with using string append as you have to construct pure strings. You just can't use that to combine numbers like you can in languages such as perl.
istringstream is for input, ostringstream for output. stringstream is input and output.
You can use stringstream pretty much everywhere.
However, if you give your object to another user, and it uses operator >> whereas you where waiting a write only object, you will not be happy ;-)
PS:
nothing bad about it, just performance issues.
std::ostringstream::str() creates a copy of the stream's content, which doubles memory usage in some situations. You can use std::stringstream and its rdbuf() function instead to avoid this.
More details here: how to write ostringstream directly to cout
To answer your third question: No, that's perfectly reasonable. The advantage of using streams is that you can enter any sort of value that's got an operator<< defined, while you can only add strings (either C++ or C) to a std::string.
Presumably when only insertion or only extraction is appropriate for your operation you could use one of the 'i' or 'o' prefixed versions to exclude the unwanted operation.
If that is not important then you can use the i/o version.
The string concatenation you're showing is perfectly valid. Although concatenation using stringstream is possible that is not the most useful feature of stringstreams, which is to be able to insert and extract POD and abstract data types.
Why open a file for read/write access if you only need to read from it, for example?
What if multiple processes needed to read from the same file?