This question already has answers here:
How do I iterate over the words of a string?
(84 answers)
Closed 9 years ago.
I have a string and I want to split it every time the char ',' appears.
I want to save the result in a vector of pointers to string.
What is the best way to do this?
"i want to split it every time that the char ',' ..."
Use std::getline and specify the delimiter (last argument) to be ','.
"I want to save the result in a vector of pointers to string"
You want to avoid using vector of pointers, believe me. Use std::vector<std::string> instead:
std::istringstream is(",,,my,,weird,string");
std::vector<std::string> tokens;
std::string token;
while (std::getline(is, token, ',')) {
if (!token.empty())
tokens.push_back(token);
}
for (int i = 0; i < tokens.size(); ++i)
std::cout << tokens[i] << " ";
outputs my weird string. Just don't forget to #include <sstream>.
boost::algorithm::split
Or write your own. This algorithm is pretty easy to write in terms of std::find.
I've used strtok to tokenize string, but this has a few drawbacks:
This is part of cstring and it's used for C-style strings, and not std::string objects.
It's kind of clumsy in terms of having to call it several times changing the parameter after the first time.
It's not ideal if you have boost available but it should work for all implementations of C++.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I made a code but it doesn't work.Can you help? In code, I wanted to take a line and if code see //n, end line.
Here is my example.
File:
I love C++! //n
My Code:
ifstream file("file.txt");
char text[250];
while(file >> text){
cout << text << " ";
if(text == "//n"){
cout << endl;
}
}
Thanks for your help.
I am unsure as to what you are trying to do, however it seems that you want to get a line worth of text. If so, you would want to change
char text[255];
....
if(text == "//n")
to
std::string text;
...
if(text == "\n")
The array comparison will not compare strings. So use the std::string to allow you to use == operator.
As C++ special character codes use a backslash rather than two forward slashes.
However, I'd also suggest using a single char rather than an array (as indexing doesn't seem to be a concern since you only access the first character in it).
If you want to read a file a word at a time:
ifstream file("file.txt");
std::string line;
while(std::getline(file, line)) {
std::stringstream linestream(line);
std::string word;
while(linestream >> word) {
std::cout << "Word: " << word << " ";
}
std::cout << "EOL\n";
}
Basically your code has a couple of issues.
'//n' is not a special character we all assume you meant '\n'.
Most operators that read text from a file will disgard the '\n' character.
operator>> will disguard white space (including \n).
getline() reads the line but drops the \n.
Thus '\n' is never in text to be compared too.
Arrays char text[255] will convert themselves into pointers easily.
Thus the comparison you are doing compares two pointers. This will never be equal.
You need a type that does something smart with == so that you compare the text.
For this you should use std::string.
As a good style guide.
Never put using namespace std; in your code. It causes more trouble when you have anything but a simple bit of throwaway code. And using it in simple throwaway code is a bad habit that will catch up to you someday.
The reason std (as well as others) is short and not standard is so that prefixing it items from the standard library is not burdensome.
std::cout << text << " "; // not hard.
std::cout << std::endl;
There is no real reason to use std::endl (debugging being an exception I suppose). In normal situations the extra flush it adds will generally cause the output to slow down perceptibly. So prefer to use '\n' unless you specifically want to force a flush.
The problem here is, your code compares pointers, instead of comparing strings (as noted also in the other answer):
if(text == "//n")
{
...
}
Here text is a pointer (actually, an array of char, but in this context it's equivalent to a pointer), and "//n" also is a pointer (also an array). Comparing two pointers is not what you want.
To fix your code so it compares strings, one of the things your code compares should be a string instead of a pointer. To mark "//n" as a string, append s to it:
if(text == "//n"s)
{
...
}
This is a bit obscure; another solution is to make text a string (as described in the other answer):
std::string text;
This question already has answers here:
How do I iterate over the words of a string?
(84 answers)
Closed 8 years ago.
In c++, how can I iterate through each line in a string? There have been plenty of questions regarding reading a file line by line, but how can I do this with a std::string?
For example, if I have the following string:
1051
2232
5152
3821
0021
3258
How would I iterate through each number?
In c++, you can use string exactly as files, using the classes defined in the sstream header:
#include <sstream>
//...
std::string str=...; // your string
std::istrstream in(str); // an istream, just like ifstream and cin
std::string line;
while(std::getline(in,line)){
//do stuff with line
}
This is a bit simplistic, but you get the idea.
You can use in just as you would use cin, e.g. in>>x etc. Hence the solutions from How do I iterate over cin line by line in C++? are relevant here too - you might want to look at them for the "real" answer (just replace cin with your own istream
Edit:
As a side note, you can create strings in the same way you print to the screen, using the ostream mechanism (like cout):
std::ostringstream out;
out << header << "_" << 3.5<<".txt";
std::string filename=out.str();
Use a tokenizer and let '\n' or '\r\n' or the appropriate newline for your OS be the token splitter..
Or if you were using a buffered file stream reader, just create a stringstream from this new string and read from the string stream instead of the file stream.
In short nothing changes except that you aren't reading from a file.
A horribly naive solution would be to make a string stream from this and assign ints or strings in a while loop from it.
When should I use stringstream instead of string::append()?
Supposing I'm going to catenate just strings.
stringstream ss;
ss << str1 << "str2" << ...
Write(ss.str());
Or:
string str;
str.reserve(10000);
str.append(str1);
str.append("str2");
...
Write(str);
Which of them is faster?
I don't know which one will be faster, but if I had to guess I'd say your second example is, especially since you've called the reserve member function to allocate a large space for expansion.
If you're only concatenating strings use string::append (or string::operator+=).
If you're going to convert numbers to their string representation, as well as format them during conversion, and then append the conversion results together, use stringstreams. I mention the formatting part explicitly because if you do not require formatting C++11 offers std::to_string which can be used to convert numeric types to strings.
string.append is much faster. Especially when you reserve.
If you are concatenating only strings, I would use string.append. I would only use stringstream when I need to automatically convert non-strings to strings for example:
const int x(42);
stringstream ss;
ss << "My favorite number is: " << x << std::endl;
Here stringstream automatically converts x to a string and appends it. I do not need to call atoi. Stringstream will convert all the basic types automatically for you. It is great for that purpose.
Also if you are only going to be directing data into the stringstream to convert it to a string later. You can use ostringstream which is for output.
I hope that helps.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Using strtok with a string argument (instead of char*)?
When using strtok() i do the following
char str[300];
while(infile) {
infile.getline(str,300);
char* token=strtok(str," ");
How can i use a string instead of the character array char str[300];
is there a way to use it to be like this,string str;
while(infile) {
infile.getline(str,300);
char* token=strtok(str," ");
I don't think you can, at least not without great care; strtok() modifies its argument, writing a \0 into it after every recognized token, and generally behaves like a function that's poorly behaved even for C, much less C++. My advice would be to look for a native C++ solution instead.
If you mean an std::string, you cannot, strtok only works with char*.
An easy solution could be that of strdup your string.c_str, and pass it to strtok.
string str;
while(infile)
{
getline(infile, str);
char* token=strtok(&str[0], " ");
}
Clean it ain't, but it will work.
EDIT: My mistake, this may not work in all circumstances.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How do I tokenize a string in C++?
hello every one i want to divide my string into two parts based on '\t' is there any built in function i tried strtok but it take char * as first in put but my variable is of type string
thanks
#include <sstream>
#include <vector>
#include <string>
int main() {
std::string str("abc\tdef");
char split_char = '\t';
std::istringstream split(str);
std::vector<std::string> token;
for(std::string each; std::getline(split, each, split_char); token.push_back(each));
}
Why can't you use C standard library?
Variant 1.
Use std::string::c_str() function to convert a std::string to a C-string (char *)
Variant 2.
Use std::string::find(char, size_t) to find a necessary symbol ('\t' in your case) than make a new string with std::string::substr. Loop saving a 'current position' till the end of line.