Finding the middle word in a string - c++

As the title suggests, I'm having trouble trying to grab the middle word out of a string, I believe my formula is wrong but I'm not completely sure where to from here to fix the issue, any help is always appreciated thank you!
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
string sentence="";
string middle="";
string midtemp="";
int count=0;
int mid=0;
cout << "Enter a sentence:" << endl;
getline(cin,sentence); //gets user input
for(int count =0; count<sentence.length();count++){
letter=sentence.substr(count,1);
int mid = sentence.length();
if (midtemp.length()>middle.length())
{ midtemp=middle;}
if (sentence[count]!=' ')
{ if(mid%2==0);
reverse(longest.rbegin(),longest.rend()); //shows the word not backwards
cout<<"Middle word is: " << sentence.substr(mid/2 -1) <<"\n" << endl;
break; //presents info to user
}
else(mid%2!=0);
{ mid/2;
cout<<"Middle word is: " << sentence.substr(mid/2 -1) <<"\n" << endl;
break; //presents info to user if number is even
}
}

To find the middle word in a string with three words use:
size_t begin_index = sentence.find(' ') + 1;
size_t end_index = sentence.find(' ', begin_index);
size_t length = end_index - begin_index;
string middle_word = sentence.substr(begin_index, length);
To find the middle word in a string with any odd number of words use:
// create string stream from sentence
istringstream ss(sentence);
// split string stream into vector of words
vector<string> words(istream_iterator<string>(ss), {});
// get middle index
size_t middle_index = (words.size() - 1) / 2;
// get middle word
const auto& middle_word = words[middle_index];
If there are an even number of words, the result is either rounded up or down until C++11, after C++11 it is rounded down. (To the word before the middle space).

#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char **argv) {
string input;
getline(cin, input);
vector<string> tokens;
string token;
for (size_t i = 0; i < input.length(); i++) {
char c = input[i];
if (c == ' ' || !input[i + 1]) {
if (!input[i + 1])
token += c;
tokens.push_back(token);
token = "";
continue;
}
token += c;
}
auto mid = tokens.size() % 2 == 0 ? tokens.begin() + tokens.size() / 2 - 1
: tokens.begin() + tokens.size() / 2;
cout << *mid;
return 0;
}

Related

Find all substring in a given string c++

I've got a problem with a program which finds all substring in a given string.
I've tried to make variable "found", which would contain a position of a previously found substring and then start searching from the position.
Here's my code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
string str1;
cin >> str >> str1;
int i = 0;
int found = -1;
while(found < str1.size()){
found = str1.find(str, found + 1);
cout<<str1.find(str, found)<<endl;
i++;
}
}
for the following input: "ab
aabb"
it doesn't print anything.
Could you help?
So a little bit of theory first:
substr(a,b) -> returns cut out of the string from position a to position b
find(a) -> returns the position of found character or set of characters 'a'. returns -1 if NOT found.
Let's examine your code:
#include <iostream>
#include <string> //not really needed here. string should already be usable
using namespace std; //in small programs is ok but with big programs this could lead to problems with using specific things that could have the same names in std and other library. So its best to avoid this and or any other using namespace you use.
int main()
{
string str; // you should really name your variables better
string str1;
cin >> str >> str1; // your variable names are unreadable at first glance
int i = 0; // iterator cool but why is it needed if you're just using find()
int found = -1; // good variable although the name "pos" would probably be better as to further explain to the programmer what the variable does
while(found < str1.size()){ //not really sure what you were going for here
found = str1.find(str, found + 1); // this could have been your while logic above instead
cout<<str1.find(str, found)<<endl; // this finds the exact same position again using more resources. your variable found stores the position so doing cout << found << here would be better
i++;
}
}
Now let's see why your code doesn't show anything on console:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
string str1;
cin >> str >> str1; //you input ab as str and abbb as str1
int i = 0;
int found = -1;
while(found < str1.size()){ //first iteration is while(-1 < 4)
found = str1.find(str, found + 1); //<-- find needs just 1 parameter. heres your problem
cout<<str1.find(str, found)<<endl;
i++;
}
}
str1.find("ab); -> function find searches for "ab" in string str1. You don't need to add where it's meant to search for. Also the fact that your while loop is dependant on found < str1.size() and not anything to do with your iterator means your loop will go on forever. whenever this happens most IDE's crash your program giving you nothing cout'ed.
Fix:
#include <iostream>
using namespace std;
int main()
{
string str;
string str1;
int pos;
cin >> str >> str1;
for(int i = 0; i < str1.size(); i++) // this or could be while(true)
{
pos = str1.substr(i).find(str); //finds your string in the rest of the line
if (pos == -1)
{
//NOT FOUND
break; //stops
}
else
{
//FOUND
cout << pos + i << endl; //pos is position in the cut out after adding i we get global position
i += pos; // skip characters after we found them to NOT be found again
}
}
}
Another possible solution would be:
Walk the input string until the point you know the substring cannot fit anymore.
For each input string position, check if each substring starts with the substring (starts_with only since C++20).
[Demo]
#include <iostream>
#include <string>
int main() {
std::string str{ "ab aab" };
std::string sub{ "ab" };
int count{};
size_t last_index{ str.size() > sub.size() ? str.size() - sub.size() : 0 };
for (size_t i{0}; i <= last_index; ++i) {
if (str.substr(i).starts_with(sub)) {
count++;
}
}
std::cout << count;
}
// Outputs: 2
int find_substr(string substr, string str) {
int postion = 0;
auto beginning = str.c_str();
int i = 0;
char* p = (char *)beginning;
while (p && '\0'!=p)
{
p = strstr(p, substr.c_str());
if (!p)
break;
cout << "A substring is at index:" << p - beginning << "\n";
p++;
};
return 0;
}
void test()
{
string substr, str;
{
substr = "ab"; str = "aabb";
cout << "Finding " << substr << " in " << str << "\n";
find_substr(substr, str);
cout << "\n";
}
{
substr = "ab"; str = "abab";
find_substr(substr, str);
cout << "\n";
}
{
substr = "a"; str = "11111111111111111111111a";
find_substr(substr, str);
cout << "\n";
}
}

print 2nd word in a string with its size in C++

I am trying to make a program in which a user enters a string and i will print out the second word in the string with its size.
The delimiter's are space( ), comma(,) and tab( ).
I have used a character array and fgets to read from user and a character pointer that points to the first element of the array.
source code:
#include"iostream"
#include<stdio.h>
#include<string>
using namespace std;
// extract the 2nd word from a string and print it with its size(the number of characters in 2nd word)
int main()
{
char arr[30], arr1[30];
char *str = &arr1[0];
cout<<"Enter a string: ";
fgets(str, 30, stdin);
int i = 0, j, count = 1, p = 0; // count is used to find the second word
// j points to the next index where the first delimiter is found.
// p is used to store the second word found in character array 'arr'
while(*(str+i) != '\n')
{
if(*(str+i) == ' ' || *(str+i) == ',' || *(str+i) == ' ')
{
count++;
if(count == 2)
{
// stroing 2nd word in arr character array
j = i+1;
while(*(str+j) != ' ' || *(str+j) != ',' || *(str+j) != ' ')
{
arr[p] = *(str+j);
cout<<arr[p];
p++;
i++;
j++;
}
break;
}
}
i++;
}
arr[p+1] = '\0'; // insert NULL at end
i = 0;
while(arr[i] != '\0')
{
cout<<arr[i];
i++;
}
cout<<"("<<i<<")"<<endl;
return 0;
}
Help me out with this.
To start, don't use std::cin for testing. Just set a value in your code for consistency and ease of development. Use this page for a reference.
#include <iostream>
#include <string>
int main() {
std::string str("this and_that are the tests");
auto start = str.find_first_of(" ,\n", 0);
auto end = str.find_first_of(" ,\n", start + 1);
std::cout << str.substr(start, end - start);
return 0;
}
And this is still somewhat of a hack, it just depends where you are going. For instance the Boost library is rich with extended string manipulation. If you are going to parse out more than just one word it can still be done with string manipulations, but ad-hoc parsers can get out of hand. There are other tools like Boost Spirit to keep code under control.
The delimiters used when extracting from a stream depends on the locale currently in effect. One (cumbersome) way to change the extraction behaviour is to create a new locale with a special facet in which you specify your own delimiters. In the below example the new locale is used to imbue a std::stringstream instead of std::cin directly. The facet creation part is mostly copy/paste from other answers here on SO, so you'll find plenty of other examples.
#include <iostream>
#include <locale> // std::locale, std::ctype<char>
// https://en.cppreference.com/w/cpp/locale/ctype_char
#include <sstream> // std::stringstream
#include <algorithm> // std::copy_n
#include <vector> // a container to store stuff in
// facet to create our own delimiters
class my_facet : public std::ctype<char> {
mask my_table[table_size];
public:
my_facet(size_t refs = 0)
: std::ctype<char>(&my_table[0], false, refs)
{
// copy the "C" locales table to my_table
std::copy_n(classic_table(), table_size, my_table);
// and create our delimiter specification
my_table[' '] = (mask)space;
my_table['\t'] = (mask)space;
my_table[','] = (mask)space;
}
};
int main() {
std::stringstream ss;
// create a locale with our special facet
std::locale loc(std::locale(), new my_facet);
// imbue the new locale on the stringstream
ss.imbue(loc);
while(true) {
std::string line;
std::cout << "Enter sentence: ";
if(std::getline(std::cin, line)) {
ss.clear(); // clear the string stream from prior errors etc.
ss.str(line); // assign the line to the string stream
std::vector<std::string> words; // std::string container to store all words in
std::string word; // for extracting one word
while(ss>>word) { // extract one word at a time using the special facet
std::cout << " \"" << word << "\" is " << word.size() << " chars\n";
// put the word in our container
words.emplace_back(std::move(word));
}
if(words.size()>=2) {
std::cout << "The second word, \"" << words[1] << "\", is " << words[1].size() << " chars\n";
} else {
std::cout << "did not get 2 words or more...\n";
}
} else break;
}
}
#include"iostream"
#include<stdio.h>
#include<string>
#include <ctype.h>
using namespace std;
int main()
{
char c;
string str;
char emp = ' ';
cout<<"Enter a string: ";
getline (cin,str);
int j = 0, count = 1, counter = 0;
for (int i = 0; i < str.length() && count != 2; i++)
{
cout<< str[i] <<endl;
if( isspace(str[i]) || str[i] == ',' || str[i] == '\t' )
{
count++;
if(count == 2)
{
j = i+1;
while(j < str.length())
{
if (isspace(str[j]) || str[j] == ',' || str[j] == '\t')
{
break;
}
cout<<str[j];
counter++;
j++;
}
cout<<endl;
}
}
}
cout<<"size of the word: "<<counter<<endl;
return 0;
}
This is a simple answer to what you want, hope to help you.
// Paul Adrian P. Delos Santos - BS Electronics Engineering
// Exercise on Strings
#include <iostream>
#include <sstream>
using namespace std;
int main(){
// Opening Message
cout << "This program will display the second word and its length.\n\n";
// Ask for a string to the user.
string input;
cout << "Now, please enter a phrase or sentence: ";
getline(cin, input);
// Count the number of words to be used in making a string array.
int count = 0;
int i;
for (i=0; input[i] != '\0'; i++){
if (input[i] == ' ')
count++;
}
int finalCount = count + 1;
// Store each word in a string array.
string arr[finalCount];
int j = 0;
stringstream ssin(input);
while (ssin.good() && j < finalCount){
ssin >> arr[j];
j++;
}
// Display the second word and its length.
string secondWord = arr[1];
cout << "\nResult: " << arr[1] << " (" << secondWord.size() << ")";
return 0;
}

C++ insertion sort from a txt file

I have to read from a .txt file and out it with a different .txt file. I have to use insertion sort in order to sort them based on two numbers. I could only get this far, I don't know how to do insertion sort in this program where I have two numbers to sort to.
Here is my code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(void)
{
int serialno[100], suratno[100], ayatno[100];
string order;
string str;
char ch;
int i = 0;
int j, temp;
ifstream fin;
fin.open("text.txt");
if(!fin)
{
cout << "Cannot open file \'text.txt\'! Quitting.\n";
exit(0);
}
while(fin)
{
fin.get(ch); //gets .
getline(fin, order, '('); //allegedly it removes the delimiter char from stream too
fin >> suratno;
fin.get(ch); //gets :
fin >> ayatno;
fin.get(ch); //gets )
fin.get(ch); //gets \n
cout << serialno << "." << order << "("<<suratno<<":<<ayatno<<")\n";
}
fin.close();
//sort algorithm
for (int i = 0; i < length; i++){
j = i;
while (j > 0 && suratno [j] < suratno [j-1]){
temp = suratno [j];
suratno [j] = suratno [j-1];
suratno [j-1] = temp;
j--;
cout << serialno << endl;
}
}
}
ofstream fout;
fout.open("newtext.txt");
if(!fout)
{
cout << "Cannot open output file\'orderedquranorders.txt\'!Quitting.\n";
exit(0);
}
i = 0;
//write sorted list to output file
fout.close();
cout << i << " orders successfully sorted and written.\n";
}
this is the text file (numbers in bracket should be used, firstly with number before colon, and secondly with number after colon):
1. Do not be rude in speech (3:159)
2. Restrain Anger (3:134)
3. Be good to others (4:36)
4. Do not be arrogant (7:13)
5. Forgive others for their mistakes (7:199)
6. Speak to people mildly (20:44)
7. Lower your voice (31:19)
8. Do not ridicule others (49:11)
9. Be dutiful to parents(17:23)
current output:
Do not be rude in speech (3:159)
Restrain Anger (3:134)
Be good to others (4:36)
Be dutiful to parents(17:23)
expected output:
Restrain Anger (3:134)
Do not be rude in speech (3:159)
Be good to others (4:36)
Be dutiful to parents(17:23)
sorted in terms of both the numbers and the serial no stays the same
In order to compare two pair of numbers, you can make comparisons like:
if(suratno[i] < suratno[i-1] || (suratno[i] == suratno[i-1] && ayatno[i] < ayatno[i-1])){
/* swap */
}
Or you can use one expression: expr = suratno * 10000 + ayatno. And make just one comparison:
if(expr[i] < expr[i-1]){
/* swap */
}
Also, I have a few observations about your algorithm/code:
Don't use using namespace std. Specially in big programs, because it can cause obscure bugs (see an example here). Instead use using std::<name> when you want to avoid std::. Ex. using std::string. In general, avoid using namespace xxxx.
I see you did parse the input lines manually, I prefer to use regular expressions, that are much more versatile and powerful, but requires a little learning.
When it's necessary to write an error message, always write to stderr stream cerr in C++.
In the sort algorithm, it's better start in 1 than 0, because the first item doesn't have a previous item to compare with.
Finally the swap can be done with an existent C++ function.
Here is your code reorganized and using regular expressions that I tried to explain as much as possible:
#include <iostream>
#include <fstream>
#include <string>
#include <regex>
#include <vector>
#include <algorithm>
using std::string;
struct Line {
int expr; // Expression used to compare
string text; // Original line without initial number
};
int main() {
std::regex linePattern(
"\\d+" // 1 or more digits
"\\. " // '. ' (dot followed by 1 space)
"(" // begin char group #1
".*" // zero or more chars
"\\(" // '(' (left parenthesis)
"(\\d+)" // char group #2 (suratno: 1+ digits)
":" // ':' (colon)
"(\\d+)" // char group #3 (ayatno: 1+ digits)
"\\)" // ')' (right parenthesis)
")" // end char group #1
);
std::smatch groups; // Regular expression found char groups
std::vector<Line> lines; // Vector to store the readed lines
// Read lines parsing content
std::ifstream fin("text.txt");
if(!fin){
std::cerr << "Cannot open file 'text.txt'! Quitting.\n";
return 1;
}
string line;
while (std::getline(fin, line))
if (std::regex_search(line, groups, linePattern) && groups.size() > 0) {
int suratno = std::stoi(groups[2]);
int ayatno = std::stoi(groups[3]);
int compExpr = suratno * 10000 + ayatno; // assumes ayatno < 10,000
lines.push_back({ compExpr, groups[1] });
}
fin.close();
// sort algorithm (better start in 1)
for (size_t i = 1; i < lines.size(); i++)
for (size_t j = i; j > 0 && lines[j].expr < lines[j - 1].expr; j--)
std::swap(lines[j], lines[j - 1]);
std::ofstream fout("newtext.txt");
if(!fout){
std::cerr << "Cannot open output file 'orderedquranorders.txt'! Quitting.\n";
return 1;
}
for (size_t i = 0; i < lines.size(); i++)
fout << i + 1 << ". " << lines[i].text << std::endl;
fout.close();
std::cout << lines.size() << " orders successfully sorted and written.\n";
return 0;
}
Note: The regular expression is really one string "\\d+\\. (.*\\((\\d+):(\\d+)\\))", I used a C/C++ feature that concatenates strings separated by spaces before compilation, so the compiler sees only one string.
Don't forget to compile with -std=c++11 option.
using namespace std; is considered bad practice and can be dangerous sometimes. Check this
Here is your solution:
#include <iostream>
#include <fstream>
#include <string>
int main()
{
int suratno[100], ayatno[100];
std::string order[100];
char ch;
int count = 0;
int tempInt;
std::string tempStr;
std::ifstream fin;
fin.open("text.txt");
if (!fin)
{
std::cout << "Cannot open file \'text.txt\'! Quitting.\n";
exit(0);
}
else
{
while (fin)
{
fin.get(ch); //gets the numbers
fin.get(ch); //gets .
getline(fin, order[count], '('); //allegedly it removes the delimiter char from stream too
fin >> suratno[count];
fin.get(ch); //gets :
fin >> ayatno[count];
fin.get(ch); //gets )
fin.get(ch); //gets \n
std::cout << count + 1 << "." << order[count] << "(" << suratno[count] << ":" << ayatno[count] << ")\n";
count++;
}
}
fin.close();
std::cout << std::endl;
// sort algorithm (we must sort two times)
for (int i = 0; i < count; i++)
{
for (int j = i; j > 0 && suratno[j] < suratno[j - 1]; j--)
{
tempInt = suratno[j];
suratno[j] = suratno[j - 1];
suratno[j - 1] = tempInt;
tempInt = ayatno[j];
ayatno[j] = ayatno[j - 1];
ayatno[j - 1] = tempInt;
tempStr = order[j];
order[j] = order[j - 1];
order[j - 1] = tempStr;
}
}
for (int i = 0; i < count; i++)
{
for (int j = i; j > 0 && suratno[j] == suratno[j - 1] && ayatno[j] < ayatno[j - 1]; j--)
{
tempInt = ayatno[j];
ayatno[j] = ayatno[j - 1];
ayatno[j - 1] = tempInt;
tempInt = suratno[j];
suratno[j] = suratno[j - 1];
suratno[j - 1] = tempInt;
tempStr = order[j];
order[j] = order[j - 1];
order[j - 1] = tempStr;
}
}
// print the sorted list just to check
for (int i = 0; i < count; i++)
{
std::cout << i + 1 << "." << order[i] << "(" << suratno[i] << ":" << ayatno[i] << ")\n";
}
// write sorted list to output file
std::ofstream fout;
fout.open("newtext.txt");
if (!fout)
{
std::cout << "Cannot open output file\'orderedquranorders.txt\'!Quitting.\n";
exit(0);
}
else
{
for (int i = 0; i < count; i++)
{
fout << i + 1 << "." << order[i] << "(" << suratno[i] << ":" << ayatno[i] << ")\n";
}
}
fout.close();
std::cout << std::endl;
std::cout << count << " orders successfully sorted and written.\n";
return 0;
}

C++ print string one word at a time, count characters, and average of characters

how can I print a single word from a string in each line with the number of characters right next to it and the average of the characters together? I'm suppose to use a string member function to convert the object into a c string. The function countWords accepts the c string and returns an int. The function is suppose to read in each word and their lengths including the average of characters. I have done how much words are in the string except I don't know how continue the rest.
For example: super great cannon boys
super 5
great 5
cannon 6
boys 4
average of characters: 5
This is my program so far:
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
int countWords(char *sentence);
int main()
{
const int size=80;
char word[size];
double average=0;
cout<<"Enter words less than " <<size-1<<" characters."<<endl;
cin.getline(word, size);
cout <<"There are "<<countWords(word)<<" words in the sentence."<<endl;
return 0;
}
int countWords(char *sentence)
{
int words= 1;
while(*sentence != '\0')
{
if(*sentence == ' ')
words++;
sentence++;
}
return words;
}
Unless this is something like homework that prohibits doing so, you almost certainly want to use std::string along with the version of std::getline that works with a std::string instead of a raw buffer of char:
std::string s;
std::getline(std::cin, s);
Then you can count the words by stuffing the line into a std::istringstream, and reading words out of there:
std::istringstream buffer(s);
auto word_count = std::count(std::istream_iterator<std::string>(s),
std::istream_iterator<std::string());
To print out the words and their lengths as you go, you could (for example) use std::for_each instead:
int count = 0;
std::for_each(std::istream_iterator<std::string>(s),
std::istream_iterator<std::string>(),
[&](std::string const &s) {
std::cout << s << " " << s.size();
++count;});
This should not be far from you requirements - I only did minimal modification to your present code.
Limits :
you'd better use
string line;
getline(cin, line);
to read the line to be able to accept lines of any size
my present code assumes
no spaces at beginning or end of line
one single space between 2 words
it should be improved to cope with extra spaces, but I leave that to you as an exercise :-)
The code :
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
int countWords(char *sentence, double& average);
int main()
{
const int size=80;
char word[size];
double average=0;
cout<<"Enter words less than " <<size-1<<" characters."<<endl;
cin.getline(word, size);
cout <<"There are "<<countWords(word, average)<<" words in the sentence."<<endl;
cout << "Average of the sentence " << average << endl;
return 0;
}
int countWords(char *sentence, double& average)
{
int words= 1;
int wordlen;
char *word = NULL;
while(*sentence != '\0')
{
if(*sentence == ' ') {
words++;
wordlen = sentence - word;
average += wordlen;
*sentence = '\0';
cout << word << " " << wordlen<< endl;
word = NULL;
}
else if (word == NULL) word = sentence;
sentence++;
}
wordlen = sentence - word;
average += wordlen;
cout << word << " " << wordlen<< endl;
average /= words;
return words;
}
For input : super great cannon boys
Output is :
Enter words less than 79 characters.
super great cannon boys
super 5
great 5
cannon 6
boys 4
There are 4 words in the sentence.
Average of the sentence 5
You can inspire here. Basically use std::getline to read from std::cin to std::string.
#include <iostream>
#include <string>
#include <cctype>
inline void printWordInfo(std::string& word) {
std::cout << "WORD: " << word << ", CHARS: " << word.length() << std::endl;
}
void printInfo(std::string& line) {
bool space = false;
int words = 0;
int chars = 0;
std::string current_word;
for(std::string::iterator it = line.begin(); it != line.end(); ++it) {
char c = *it;
if (isspace(c)) {
if (!space) {
printWordInfo(current_word);
current_word.clear();
space = true;
words++;
}
}
else {
space = false;
chars++;
current_word.push_back(c);
}
}
if (current_word.length()) {
words++;
printWordInfo(current_word);
}
if (words) {
std::cout << "AVERAGE:" << (double)chars/words << std::endl;
}
}
int main(int argc, char * argv[]) {
std::string line;
std::getline(std::cin, line);
printInfo(line);
return 0;
}
Going along the lines of what you already have:
You could define a countCharacters function, like your countWords:
int countCharacters(char *sentence)
{
int i;
char word[size];
for(i = 0; sentence[i] != ' '; i++) //iterate via index
{
word[i] = sentence[i]; //save the current word
i++;
}
cout <<word<< <<i<<endl; //print word & number of chars
return i;
}
which you can call inside your countWords function
int countWords(char *sentence)
{
int words = 1;
for(int i; sentence[i] != '\0';) //again this for loop, but without
//increasing i automatically
{
if(sentence[i] == ' ') {
i += countCharacters(sentence[++i]); //move i one forward to skip
// the space, and then move
// i with the amount of
// characters we just counted
words++;
}
else i++;
}
return words;
}

Count the number trailing blank space in a string

Can anyone help me in decreasing the complexity of the code below which counts the number of trailing blank spaces in a string.
void main()
{
string url = "abcd ";
int count = 1;
for (int i = 0; i < url.length(); i++)
{
if (url.at(i) == ' ')
{
for (int k = i + 1; k < url.length(); k++)
{
if (url.at(k) != ' ')
{
count = 1;
break;
}
else
{
count++;
i++;
}
}
}
}
cout<< count;
}
#include <iostream>
#include <string>
#include <algorithm>
#include <cstring>
using namespace std;
int main()
{
string url = "abcd "; // four spaces
string rev = url;
reverse(rev.begin(), rev.end());
cout << "There are " << strspn(rev.c_str(), " ") << " trailing spaces." << endl;
return 0;
}
We can do this without reversing the string, and without using a C function like strspn. For example, look up the string::find_last_not_of function. It will find the last character in the string which is not in the specified set, and return its position. If your set is the set " " (space) then it finds the last non-space character. The difference between that position and the string length is the count of trailing spaces.
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
int main()
{
string url = "abcd "; // four spaces
size_t last_nonspace = url.find_last_not_of(" ");
cout << "There are " << url.length() - last_nonspace - 1 << " trailing spaces." << endl;
return 0;
}
Note that if there is no non-space character in the string (the string is either empty or contains only spaces), the find_last_not_of function returns string::npos which is just (size_t) -1, the largest value of size_t. When this is subtracted from the length, and then 1 is subtracted, the resulting value is just the length. The arithmetic works out in all cases.
start backward counting the white space
void main() {
string url = "abcd ";
int count = 0;
for (int i = url.length(); i > 0; i--) {
if (url.at(i) == ' ') {
count++;
} else {
break;
}
}
cout<< count;
}
You can do this by using the find_if() algorithm function:
#include <algorithm>
#include <string>
#include <cctype>
#include <iostream>
using namespace std;
int main()
{
string s = "This string has spaces at the end ";
string::iterator it =
find_if(s.rbegin(), s.rend(), [](char ch) { return !isspace(ch); }).base();
cout << "The number of trailing spaces is " << std::distance(it, s.end());
}
Basically we start from the end of the string, and let find_if() find the first non-space character (I used isspace instead of the hard-coded 32).
After that, the iterator that is returned will point to the non-space character, so it's a matter of just knowing the "distance" between that point and the end (that is what std::distance will do for us).