Is there some way to get StringStream to read characters A through B of a string?
For example, something like (but not):
stringstream mystringstream;
mystringstream.read(char* s, streamsize n, **int firstcharacter**);
Thanks for your help.
EDIT: By A through B I mean, for example, the third through fifth characters.
EDIT: Example: get characters three through five of "abcdefghijklmnop" would give "cde".
or, if you need a substring in position A through B, you can do
string s = mystring.substr(A, B-A+1); // the second parameter is the length
if this must be a stringstream, you can do
string s = mystringstream.str().substr(A, B-A+1);
You can use the substr-method:
std::string foo = "asdfersdfwerg";
std::cout << foo.substr(5, 4) << std::endl;
This will print rsdf.
Related
I want to combine the first 4 characters of each line in txt file and compare it with the keyword I have, but
when I combine the characters, I get the sum of these 4 characters' ascii numbers(whatever).
How can I solve this problem. My code is here:
When I debuged, I saw the string search(variable) was 321.
int main() {
ifstream file("sentence.txt");
if (file.is_open()) {
string line;
while (getline(file, line)) {
string search = to_string(line[0] + line[1] + line[2]); // you see what I mean
if ("dog" == search) {
cout << "there is dog";
}
else {
cout << "there is no dog"<<endl;
}
}
}
}
The function std::to_string() is designed to convert a number into a string representation. It is not what you need.
There is no need to create the new string search to check whether the string line starts with the string "dog".
Creating the new string search is inefficient.
Instead, you could write for example
if ( line.compare( 0, 3, "dog" ) == 0 ) {
cout << "there is dog";
}
else {
cout << "there is no dog" << endl;
}
Or, if your compiler supports C++20, you can also write:
if ( line.starts_with( "dog" ) ) {
cout << "there is dog";
}
else {
cout << "there is no dog" << endl;
}
line[0], line[1], and line[2] are chars, not std::strings. char is an integer type, so adding two chars together results in a single integer that is the sum of the two operands. It does not produce a std::string that is the concatenation of the two chars.
To get a substring of a std::string use the substr member function:
std::string search = line.substr(0, 3);
Or, if you actually need to construct a std::string from individual chars, use the constructor that accepts a std::initializer_list<char>:
std::string search{line[0], line[1], line[2]};
A string made from the first characters of line can be obtained via std::substr. In this case I'd actually prefer the constructor that takes two iterators:
std::string first3chars{line.begin(),line.begin()+3};
Take care of lines that are less than 3 characters.
Your code adds the values of three chars. Adding chars via + does not concatenate them, and if it would why call std::to_string on the result? char is an integer type and what you see as 321 is the result of adding the number representations of the first 3 characters in line.
Is there a way for you to cast those chars (which appear to be integer type for some reason) into char type once again. Perhaps that ought to resolve the issue in case the "to_string" concatenates those 3 inputs into one; additionally intelli-sense should do the trick of explaining parameter usage and returning value.
The problem with this code is that when you access an element of a string you get a character which is an ASCII number, when you try to sum two characters you are adding their ASCII codes.
In your specific case, as you want sequential characters, the best solution would probably be to use the substr function (documentation) for strings. Otherwise, you would probably need to convert one of the characters to a string and then “add” the other characters to it.
How can I use getline() to read words form a line that I have stored in a string?
For example:
char ch[100],w[20];
cin.getline(ch,100);
Now can I use getline to count the number of words in ch? I don't want to use a delimiter to directly count words from ch. I want to read words from ch and store them in w.
I have tried using ch in getline as a parameter.
getline is implemented in the standard as either a stream method, or a string method which takes a stream: http://en.cppreference.com/w/cpp/string/basic_string/getline
There is no standard implementation of getline which does not require a stream.
That said you can use ch to seed a istringstream to count the words in the string, but basic_istream<CharT, Traits>& getline(basic_istream<CharT, Traits>&& input, basic_string<CharT, Traits, Allocator>& str) assumes a newline as the delimiter so that's not what you're going to want to count words. Similarly, a getline that takes a delimiter will only break on a specific character. Instead you could use basic_istream& basic_istream::operator>> which will split words on all whitespace characters:
istringstream foo(ch);
for(auto i = 1; foo >> w; ++i) {
cout << i << ": " << w << endl;
}
Live Example
Just as a note here, defining char w[20] is just begging for an out of bounds write. At a minimum you need to define that such that if ch is filled with non-whitespace characters, w can contain it all. You could do that by defining char w[100].
But if someone were to come and increase the size of ch without changing the size of w and then you'd be in trouble again. In C++17 you could define w like this char w[size(ch)] prior to that you could do char w[sizeof(ch) / sizeof(ch[0])]
But your best option is probably to just make both w and ch strings so they can dynamically resize to accommodate user input.
When disabling whitespace skipping with chars and strings the behavior is different. It seems the only way to extract an entire string (including whitespace characters) is to use chars and noskipws. But this is not possible with strings because it won't extract after the first space.
std::string test = "a b c";
char c;
std::istringstream iss(test);
iss.unsetf(std::ios_base::skipws);
while (iss >> c)
std::cout << c;
will output a b c but change c to string and it only outputs a.
The >> operator for a string extracts words, and stops at the
first white space it sees. If it doesn't skip initial white
space, then it stops immediately, and returns an empty string.
You don't say how you want the string to be delimited. To read
until the end of line, just use std::getline. To read until
the end of file, you can use something like:
std::istringstream collector;
collector << iss.rdbuf();
std::string results = collector.str();
It's not the most efficient, but if the file is small, it will
do.
All:
I got one question in string parsing:
For now, if I have a string like "+12+400-500+2:+13-50-510+20-66+20:"
How can I do like calculate total sum of each segment( : can be consider as end of one segment). For now, what I can figure out is only use for to loop through and check +/- sign, but I do not think it is good for a Universal method to solve this kind of problem :(
For example, the first segment, +12+400-500+2 = -86, and the second segment is
+13-50-510+20-66+20 = -573
1) The number of operand is varied( but they are always integer)
2) The number of segment is varied
3) I need do it in C++ or C.
I do not really think it as a very simple question to most newbie, and also I will claim this is not a homework. :)
best,
Since the string ends in a colon, it is easy to use find and substr to separate out parts of the string partitioned by ':', like this:
string all("+12+400-500+2:+13-50-510+20-66+20:");
int pos = 0;
for (;;) {
int next = all.find(':', pos);
if (next == string::npos) break;
string expr(all.substr(pos, (next-pos)+1));
cout << expr << endl;
pos = next+1;
}
This splits the original string into parts
+12+400-500+2:
and
+13-50-510+20-66+20:
Since istreams take leading plus as well as leading minus, you can parse out the numbers using >> operator:
istringstream iss(expr);
while (iss) {
int n;
iss >> n;
cout << n << endl;
}
With these two parts in hand, you can easily total up the individual numbers, and produce the desired output. Here is a quick demo.
You need to seperate operands and operators. To do this you can use two queue data types one for operands and one for operators
split by :, then by +, then by -. translate into int and there you are.
Your expression language seems regular: you could use a regex library - like boost::regex - to match the numbers, the signs, and the segments in groups directly, with something like
((([+-])([0-9]+))+)(:((([+-])([0-9]))+))+
I have f.e. "I am working as a nurse."
How Can I or which function use to get word from letter number 1 to space or to letter number 11?
So should I get " am working "
To read a word from a stream use operator>> on a string
std::stringstream stream("I am working as a nurse.");
std::string word;
stream >> word; // word now holds 'I'
stream >> word; // word now holds 'am'
stream >> word; // word now holds 'working'
// .. etc
It is not totally clear what you want, but from your example it seems like you want the substring that starts at character 1 and ends on the character 11 places later (that's 12 characters total). That means you want string::substr:
std::string str("I am working as a nurse");
std::string sub = str.substr(1,12);
char[] source = "I am working as a nurse."
char[11] dest;
strncpy(dest, &source[1], 10)