Counting a String within a string - c++

I'm told to ask the user for a string ( a sentence). Then the user is asked to input another string to search in string 1 (the sentence). The program has to count the number of times the second string shows up in the first string. I'm not getting any errors but it's is not counting the letters. This is the result i get:
Enter a sentence:i love to eat soup
Enter string to search: ou
There are 0 of the string ou in the first string you provided.
Can someone please tell me what i'm doing wrong? I'm a beginner at c++ so i'm having some trouble understanding.
#include <iostream>
#include <string>
using namespace std;
int main() {
string sentence;
string search;
int count = 0;
cout<<"Enter a sentence:";
getline (cin, sentence);
cout<<"Enter string to search:";
getline (cin, search);
cout << "There are " << count << " of the string " << search << " in the first string you provided." <<"\n";
for (int i=0; i < sentence.size(); ++i)
{
if (sentence == search)
count++;
}
return count;
}

Two issues:
You print count before you calculate it.
You are not actually searching for a substring. You should look at the documentation for std::string to find an appropriate way to search for substrings. However, you are on the right track.

Well, you're trying to output the results before calculating them.
Also, == is for exact matches, not substring searches.

You have your cout print line after the loop where you search for the string and set the count. Move it below that loop.

looks like you should put the cout statement in the end of this method. Because in your code, count is always 0 when you output it

You should modify your loop so that it really searches for substrings and count their occurrences:
string::size_type pos = sentence.find(search);
while (pos != string::npos)
{
pos = sentence.find(search, pos + search.size());
count++;
}
Also, you most likely want to move this line after the point where you actually compute the value of count:
cout << "There are " << count << ...
Otherwise, it will obviously output the value to which count was initialized originally (i.e. 0).

Related

Characters after a space is not being printed out

I was using character arrays to get inputs from the user then display the output afterwards. However, every time I enter values with spaces in between, only the first word before the space is printed.
For instance, this is what I typed:
Customer No.: 7877 323 2332
This will be the output:
Customer No.: 7877
I already searched for possible solutions but I can't seem to find the right solution.
This is my code for reference:
#include<iostream>
using namespace std;
int main()
{
char custNum[10] = " "; // The assignment does not allow std::string
cout << "Please enter values for the following: " << endl;
cout << "Customer No.: ";
cin >> custNum;
cout << "Customer No.: " << custNum << endl;
}
Another option is to use std::basic_istream::getline to read the entire string into the buffer and then remove the spaces with a simple for loop. But when using plain-old character arrays don't skimp on buffer size. It is far better to be 1000-characters too long than one-character too short. With your input, your absolute minimum size of custNum is 14 characters (the 13 shown plus the '\0' (nul-terminating) character. (rough rule-of-thumb, take your longest estimated input and double it -- to allow for user-mistake, cat stepping on keyboard, etc...)
In you case you can simply do:
#include <iostream>
#include <cctype>
int main() {
char custNum[32] = " "; // The assignment does not allow std::string
int wrt = 0;
std::cout << "Please enter values for the following:\nCustomer No.: ";
if (std::cin.getline(custNum, 32)) { /* validate every input */
for (int rd = 0; custNum[rd]; rd++)
if (!isspace((unsigned char)custNum[rd]))
custNum[wrt++] = custNum[rd];
custNum[wrt] = 0;
std::cout << "Customer No.: " << custNum << '\n';
}
}
The two loop counters rd (read position) and wrt (write position) are simply used to loop over the original string and remove any whitespace found, nul-terminating again when the loop is left.
Example Use/Output
$ ./bin/readcustnum
Please enter values for the following:
Customer No.: 7877 323 2332
Customer No.: 78773232332
Also take a look at Why is “using namespace std;” considered bad practice? and C++: “std::endl” vs “\n”. Much easier to build good habits now than it is to break bad ones later... Look things over and let me know if you have questions.
Apart from std::getline, if you are going to use C-style strings, try the following code:
int main() {
char* str = new char[60];
scanf("%[^\n]s", str); //accepts space a a part of the string (does not give UB as it may seem initially
printf("%s", str);
return 0;
}
Also, if you absolutely need it to be a number, then use atoi
int ivar = std::atoi(str);
PS Not to forget gets (!!dangerous!!)
char* str;
gets(str);
puts(str);
cin >> int_variable will stop reading input when it reaches the first character that isn't a valid part of a number. C++ does not consider spaces part of a number, so it stops reading as soon as it encounters one.
You could use std::getline to read into a string instead, then remove the spaces from the string before converting to an integer. Or maybe in this case you don't even need the integer and can leave it as a string.

Ignore Spaces Using getline in C++ Palindrome homework

I am trying to skip the spaces in my code using getline();
I think I solved the spacing problem, but I'm trying to make the code check from the beginning of the word and the end of the word at the same time, so that when I type sentences like "ufo tofu" it will come back as a palindrome.
I've tried removing the spaces, but it only causes the system to return me an error.
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main() {
string userInput;
int startInput;
int endInput;
bool isPalindrome = true;
startInput = userInput.length();
getline (cin, userInput);
cin.ignore();
for (int i = 0; i<(startInput/2); i++){
if (userInput[i] != userInput[(startInput -1) -i])
isPalindrome = false;
}
if (isPalindrome){
cout << userInput << " is a palindrome" << endl;
}
else {
cout << userInput << " is not a palindrome" << endl;
}
return 0;
}
I am trying to make the output come back as "is not a palindrome" when I submit my code to be graded.
These are the two errors that are coming back;
4: Compare output
0 / 2
Output differs. See highlights below.
Special character legend
Input
statistics
Your output
statistics is a palindrome
Expected output
statistics is not a palindrome
6: Compare output
0 / 2
Output differs. See highlights below.
Special character legend
Input
evil is alive
Your output
evil is alive is a palindrome
Expected output
evil is alive is not a palindrome
string s;
do {
getline(cin, s);
}while(s.empty());
s.erase((remove(s.begin(),s.end(),' ')),s.end());
cout<<s<<endl;
Let's say your string s is ufo tofu. It will after erasing all spaces become ufotofu. That way you can easily check if it's palindrome or not.
How does this thing work ?
Well we declare a string called s. In that string, we will store our ufo tofu input.
We use do-while loop to input our "sentence" into a string. We could use just getline(cin, s);, but if you pressed enter-key once, it would stop your program.
Next thing, we use function combination of functions remove and erase: As the beginning parameter we use function remove, which finds all the spaces in the string, pushes them to the end of the container (in our case string s), and returns beginning iterator of that "pushing", and the second parameter tells us to remove every single element of container from that beginning iterator to the end.
We just print out the string, but now without spaces!
I think this is really simple way to do it, but if it can't be useful to you, I am sorry for wasting your time reading all of this! :)

Using find_first_of with a string instead of a set of predefined characters in c++

I want to take in a code, for example ABC and check whether the characters in the code appear in that exact order in a string, for example with the code ABC, and the string HAPPYBIRTHDAYCACEY, which meets the criteria. The string TRAGICBIRTHDAYCACEY with the code ABC however does not pass, because there's a "c" before the "b" after the "a". I want to use the find_first_of function to search through my string, but i want to check for any of the characters in "code", without knowing what characters are in "code" beforehand. Here is my program so far:
#include <iostream>
#include <string>
using namespace std;
int main() {
string code, str, temp;
int k = 0;
int pos = 0;
cin >> code >> str;
while (k < code.size()) {
pos = str.find_first_of(code,pos);
temp[k] = str[pos];
++k;
++pos;
}
cout << temp << endl; // debug. This is just outputs a newline when i
//run the program
if (temp == code) {
cout << "PASS" << endl;
}
else {
cout << "FAIL" << endl;
}
return 0;
}
I think your best bet is to find just the first character, once found, find the next in the remainder of the string, repeat until end of string or all characters found (and return false or true, respectively).
I don't think there's anything builtin for this. If the characters would need to appear directly after each other, you could use std::string::find() which searches for a substring, but that is not what you want.

How can I find the number of words in a list?

Hey guys I have this assignment I'm working on and I need some help with this question. I was given a text document with thousands of words and I have to find the number of words of every possible length and print how many there are in a table. This is what I got so far
inStream.open("EnglishWords.txt", ifstream::in);
string word;
//int number of letters;
//int number of words;
while (inStream) {
inStream >> word;
if (word.length() == //Something..)
//print << number of letters << number of words;
}
So I basically have nothing. Any of you guys able to help me out here? or give me direction of how i should start?
You can make an std::map which stores two ints and do this:
std::map<int, int> map;
while (inStream) {
map[word.length()]++; // increment number of words for given length
}
then to print all the words of each length, you can make a for loop:
for (auto i = 0; i < MAX_LENGTH; ++i) {
std::cout << "words of length " << i << ": " << map[i] << '\n';
}
I haven't tested it but this is just an idea.
P.S. Edits made thanks to Ben who cleared up the question's purpose.

Read input numbers separated by spaces

This may be a total beginner's question, but I have yet to find an answer that works for me.
Currently, I'm writing a program for a class that takes in a user's input (which can be one or more numbers separated by spaces), then determines whether the number is prime, perfect, or neither. If the number is perfect, then it will display the divisors.
Thus far, I've already written the code for the prime, perfect, and listing the divisors. I'm stuck on the input portion of my program. I don't know how to get the input that's separated by spaces to go through my loops one at a time.
This is my current program:
cout<<"Enter a number, or numbers separated by a space, between 1 and 1000."<<endl;
cin>>num;
while (divisor<=num)
if(num%divisor==0)
{
cout<<divisor<<endl;
total=total+divisor;
divisor++;
}
else divisor++;
if(total==num*2)
cout<<"The number you entered is perfect!"<<endl;
else cout<<"The number you entered is not perfect!"<<endl;
if(num==2||num==3||num==5||num==7)
cout<<"The number you entered is prime!"<<endl;
else if(num%2==0||num%3==0||num%5==0||num%7==0)
cout<<"The number you entered is not prime!"<<endl;
else cout<<"The number you entered is prime!"<<endl;
return 0;
It works, but only for a single number. If anyone could help me to get it to be able to read multiple inputs separated by spaces, it'd be greatly appreciated. Also, just a side note, I do not know how many numbers will be entered, so I can't just make a variable for each one. It will be a random amount of numbers.
Thanks!
By default, cin reads from the input discarding any spaces. So, all you have to do is to use a do while loop to read the input more than one time:
do {
cout<<"Enter a number, or numbers separated by a space, between 1 and 1000."<<endl;
cin >> num;
// reset your variables
// your function stuff (calculations)
}
while (true); // or some condition
I would recommend reading in the line into a string, then splitting it based on the spaces. For this, you can use the getline(...) function. The trick is having a dynamic sized data structure to hold the strings once it's split. Probably the easiest to use would be a vector.
#include <string>
#include <vector>
...
string rawInput;
vector<String> numbers;
while( getline( cin, rawInput, ' ' ) )
{
numbers.push_back(rawInput);
}
So say the input looks like this:
Enter a number, or numbers separated by a space, between 1 and 1000.
10 5 20 1 200 7
You will now have a vector, numbers, that contains the elements: {"10","5","20","1","200","7"}.
Note that these are still strings, so not useful in arithmetic. To convert them to integers, we use a combination of the STL function, atoi(...), and because atoi requires a c-string instead of a c++ style string, we use the string class' c_str() member function.
while(!numbers.empty())
{
string temp = numbers.pop_back();//removes the last element from the string
num = atoi( temp.c_str() ); //re-used your 'num' variable from your code
...//do stuff
}
Now there's some problems with this code. Yes, it runs, but it is kind of clunky, and it puts the numbers out in reverse order. Lets re-write it so that it is a little more compact:
#include <string>
...
string rawInput;
cout << "Enter a number, or numbers separated by a space, between 1 and 1000." << endl;
while( getline( cin, rawInput, ' ') )
{
num = atoi( rawInput.c_str() );
...//do your stuff
}
There's still lots of room for improvement with error handling (right now if you enter a non-number the program will crash), and there's infinitely more ways to actually handle the input to get it in a usable number form (the joys of programming!), but that should give you a comprehensive start. :)
Note: I had the reference pages as links, but I cannot post more than two since I have less than 15 posts :/
Edit:
I was a little bit wrong about the atoi behavior; I confused it with Java's string->Integer conversions which throw a Not-A-Number exception when given a string that isn't a number, and then crashes the program if the exception isn't handled. atoi(), on the other hand, returns 0, which is not as helpful because what if 0 is the number they entered? Let's make use of the isdigit(...) function. An important thing to note here is that c++ style strings can be accessed like an array, meaning rawInput[0] is the first character in the string all the way up to rawInput[length - 1].
#include <string>
#include <ctype.h>
...
string rawInput;
cout << "Enter a number, or numbers separated by a space, between 1 and 1000." << endl;
while( getline( cin, rawInput, ' ') )
{
bool isNum = true;
for(int i = 0; i < rawInput.length() && isNum; ++i)
{
isNum = isdigit( rawInput[i]);
}
if(isNum)
{
num = atoi( rawInput.c_str() );
...//do your stuff
}
else
cout << rawInput << " is not a number!" << endl;
}
The boolean (true/false or 1/0 respectively) is used as a flag for the for-loop, which steps through each character in the string and checks to see if it is a 0-9 digit. If any character in the string is not a digit, the loop will break during it's next execution when it gets to the condition "&& isNum" (assuming you've covered loops already). Then after the loop, isNum is used to determine whether to do your stuff, or to print the error message.
You'll want to:
Read in an entire line from the console
Tokenize the line, splitting along spaces.
Place those split pieces into an array or list
Step through that array/list, performing your prime/perfect/etc tests.
What has your class covered along these lines so far?
int main() {
int sum = 0;
cout << "enter number" << endl;
int i = 0;
while (true) {
cin >> i;
sum += i;
//cout << i << endl;
if (cin.peek() == '\n') {
break;
}
}
cout << "result: " << sum << endl;
return 0;
}
I think this code works, you may enter any int numbers and spaces, it will calculate the sum of input ints
std::vector<int> num{};
int buf;
do{
std::cin >> buf;
num.push_back(buf);
}while(std::cin.peek() == ' ');
In C language you can to it using scanf like this:
scanf('%d %d',&a,&b);