I managed to finish this homework problem, the only issue is that it did not count instances of a substring in a string properly to include uppercase T's
PROMPT FOR QUESTION:
Write a program that counts all of the occurrences of a given substring within a larger string. You should declare string variables like string sentence = ""; and string subst = "";
Your program should input the sentence and the substring and then print out the number of times the substring appears.
Test your program with the following two examples:
sentence - "The address is 1212 Walnut Street and the time is 12:12 on July 12 2012."
subst = "12"
(Answer = 6)
sentence - "The area of the rectangle is less than the area of the triangle."
subst = "the" (NOTE: You should also count the beginning word The with an uppercase T.)
(Answer = 4)
//#define NOMINMAX // <--- Only needed if you should include "Window.h". Does not define the min and max macros from "Windows.h".
#include <iostream>
//#include <iomanip> // setw(), fixed, setprecision, std::quoted().
//#include <limits>
#include <string>
//#include <vector>
#include <cctype> // <--- For "std::tolower() and std::toupper()" + others.
//#include <algorithm>
//#include <fstream>
// <--- This section would be any header files in double quotes.
usingnamespace std; // <--- Best not to use.
int main()
{
string sentence = ""; // <--- Strings are empty when defined and do not need initialized.
string subst = ""; // <--- The empty ("") do nothing. Its still empty with no size.
cout << "Enter sentence: -\n--> "; // <--- Changed.
getline(cin, sentence);
for (size_t idx = 0; idx < sentence.size(); idx++)
{
sentence[idx] = static_cast<char>(std::tolower(static_cast<unsignedchar>(sentence[idx])));
}
cout << "Enter Substring: -\n--> "; // <--- Changed.
getline(cin, subst);
for (size_t idx = 0; idx < subst.size(); idx++)
{
subst[idx] = static_cast<char>(std::tolower(static_cast<unsignedchar>(subst[idx])));
}
int count = 0;
int nPos = sentence.find(subst, 0);
while (nPos != string::npos)
{
count++;
nPos = sentence.find(subst, nPos + subst.size());
}
cout << count << '\n';
return 0; // <--- Not required, but makes a good break point for testing.
}
Now there is nothing wrong with being lazy and just copying header files, but there is no point in including header files that you do not need or use. It just adds extra code to your program. This way as you grow you can uncomment header files that you do need.
The 2 for loops will change the inputted strings to all lower case letters, so that the ".find" will find all the correct matches.
When you use the ".find" it will compare 1 character at a time, so the letter "T" which has an ASCII value of 116 decimal while "t" which has an ASCII value of 148 decimal. These 2 values do not match. and that is why "The" is not considered a match to "the".
If you had mentioned your operating system and IDE I may have some suggestions for you.
For some versions of some compilers (gcc?? - VS was OK), you had to wrap tolower into a lambda to compile as an argument to std::transform(). That's why I started to use a range-for function.
Do all current compilers now allow this form for std::transform() ?