473,320 Members | 1,879 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Beginners: Count occurrences of a string within a string

I'm sure I have a few things wrong here. But I am stuck on how to do
a recurring search. Also my statement cin >quote; acts weird. If I
enter more than one word it blows right past cin >findMe; and
completes and exits the code. If you string for cin >quote; is one
word it behaves correctly or at least in that regard!
#include <iostream>
#include <string>
using namespace std;

string quote;
string findMe;
int foundIt(string str1, string str2);

int main ()
{
cout << " \n Enter a sentence or two:" << endl;
cin >quote;
cout << " \n Enter string to search for:" << endl;
cin >findMe;

cout << foundIt(quote, findMe);
}
int foundIt(string str1, string str2)
{
size_t pos;
int x = 0;

pos = str1.find(str1);
if (pos!=string::npos)
x++;

return x;
}
Feb 27 '08 #1
3 2476
yogi_bear_79 wrote:
I'm sure I have a few things wrong here. But I am stuck on how to do
a recurring search. Also my statement cin >quote; acts weird. If I
enter more than one word it blows right past cin >findMe; and
completes and exits the code.
The >operator, when applied to an input stream on the left and a
string on the right, skips any whitespace on the input stream, and then
reads in a single word, up until the next whitespace character (or the
end of the input stream). Thus, if you enter two words on a single line,
your code will print the first prompt, read the first word into quote
(leaving the second), print the second prompt, and read the next word
into findMe (leaving any remaining input, such as the final newline, in
the input stream). It won't wait to receive a second line, because it
already has a second word to read in from the first line.

If reading in a line is what you wanted, rather than words, you should
consider the getline() function.
int foundIt(string str1, string str2)
Note that str1 and str2 are not the same strings as quote and findMe,
but are instead entirely new strings to which have been copied the
_contents_ of quote and findMe. To avoid the needless copying, you
should use references-to-string as the parameter types, rather than
plain strings.

Also, since you're not going to modify the strings, you'd do well to
make them references to _const_ strings, to tell the caller that you
won't be changing them (which is particularly helpful in cases when the
caller itself has promised _its_ caller not to modify these strings):

int foundIt(const string &str1, const string &str2)
{
size_t pos;
size_t pos = 0;
int x = 0;

pos = str1.find(str1);
if (pos!=string::npos)
x++;
while (pos != string::npos) {
str1.find(str2, pos);
cout << "Found " << str2 << " at " << pos << '.' << endl;
}
>
return x;
}

--
Micah J. Cowan
Programmer, musician, typesetting enthusiast, gamer...
http://micah.cowan.name/
Feb 27 '08 #2
On Feb 27, 4:37 am, yogi_bear_79 <yogi_bear...@yahoo.comwrote:
I'm sure I have a few things wrong here. But I am stuck on
how to do a recurring search. Also my statement cin >quote;
acts weird. If I enter more than one word it blows right past
cin >findMe; and completes and exits the code. If you
string for cin >quote; is one word it behaves correctly or
at least in that regard!
So how do you want to decide how much text to read with the
first >>. If you want a word (skipping any white space which
precedes it), use >>. If you want a line, use getline(). If
you want the entire file, you can do so using
istreambuf_iterators, or with something like s <<
std::cin.rdbuf(), where s is a istringstream, but then you'll
have read end of file, and not be able to enter the search
string. If you want some other convention, you'll probably have
to program it. (Under Unix, a line consisting of a single '.'
is a frequent convention. This could be done something like:

std::string line ;
while ( std::getline( std::cin, line ) && line != "." ) {
quote += line + '\n' ;
}

. I'd definitely put this in a separate function, however.)

For the lookup, I'd generally prefer the standard algorithms
over the member functions of std::string. If you're learning,
I'd especially prefer them; they represent the usual idiom for
processing any container, and using them will get you used to
iterators in general. Something like:

int
countMatches(
std::string const& text,
std::string const& toMatch )
{
int result = 0 ;
for ( std::string::const_iterator current
= std::search( text.begin(), text.end(),
toMatch.begin(),
toMatch.end() ) ;
current != text.end() ;
current = std::search(
current + toMatch.size(), text.end(),
toMatch.begin(), toMatch.end() ) {
++ result ;
}
return result ;
}

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Feb 27 '08 #3
On Feb 28, 2:00 am, yogi_bear_79 <yogi_bear...@yahoo.comwrote:
On Feb 26, 10:58 pm, Micah Cowan <mi...@cowan.namewrote:
yogi_bear_79 wrote:
[...]
James, I think your code was a bit further ahead than I am
supposed to know at this point!
I'm not sure how? You should be learning the standard
algorithms long before the specific functions of std::string
(which I probably wouldn't bother teaching at all), and you
should be learning iterators before dealing with pos in a
string. (But of course, you can apply the exact same algorithm
using the position and std::string::find instead of the
iterators and std::search.)
#include <iostream>
#include <string>
using namespace std;
int findIt(const string &str1, const string &str2);
int main ()
{
string quote;
string findMe;
cout << " \n Enter a sentence or two:" << endl;
getline (cin,quote);
cout << " \n Enter string to search for:" << endl;
getline (cin,findMe);
cout << findIt(quote, findMe);}
int findIt(const string &str1, const string &str2)
{
size_t pos = 0;
int x = 0;
while (pos != string::npos) {
pos = str1.find(str2, pos);
cout << pos<<endl;
pos = pos+str2.size();
What happens in this line when str1.find returns
std::string::npos?
}
You really do want the loop I proposed:

for ( size_t pos = str1.find( str2 ) ;
pos != std::string::npos ;
pos = str1.find( str2, pos + str2.size() ) {
// Whatever you do when you find a match...
}

As a general rule: prefer for, with no modification of the
control variable outside of the third part. It's much easier to
get right. (If you need the value of the control variable after
the loop, either move the first part of the for before the loop,
or rewrite the loop as a while. And of course, don't try to
force things which don't fit into this pattern.)

You're problem, of course, is that you're modifying the control
variable twice in the loop, and the first modification might
cause the loop invariant (pos != std::string::npos) to be
invalid. The only operations which should possibly invalidate
the loop invariant should be at the end of the loop. A for
makes this clearer---the only operations which might invalidate
the loop invariant should be in the third part of the for.
return x;
}
--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Feb 28 '08 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: jester.dev | last post by:
Hello, I'm learning Python from Python Bible, and having some problems with this code below. When I run it, I get nothing. It should open the file poem.txt (which exists in the current...
21
by: rccf6178 | last post by:
Hi all, Do anyone know how to write a C program to count the frequency of a certain key pattern in a given datafile? Input: • Three alpha-numeric keys separated by space • A data file...
4
by: sibingpeter | last post by:
Hi there, Im trying to find the right way to code the loop to count the number of occurences of a given substring in a string. Im able to find the first occurence using the strstr function, but...
4
by: thomaz | last post by:
Hi.... There is a string method to count the total number of a specified character in a string. EX: count the total of (*) in a string *** Test *** Thanks....
11
by: Jon | last post by:
I want to count the number of instances of a certain string(delimiter) in another string. I didn't see a function to do this in the framework (if there is, please point me to it). If not, could...
6
by: dBNovice | last post by:
Hey group, I am trying to do a count of the number of papers in a table. The table has a PaperID that differentiates each paper , e.g. 004.1. Some papers are reused. The reused paper is given...
3
by: Dana King | last post by:
I'm looking for some other developers opinions, I'm trying to find the best way to count strings within a string using VB.net. I have tested five methods and have found the String.Replace method...
9
by: nick048 | last post by:
Hi to All, I need to search the string occurencies in a structure like this: struct node { char info; struct node *next; };
3
by: Beeteh | last post by:
Hello everybody! I'm a so-called newbie at programming in C/C++ and I'm currently working on a poject that searches for a particular string in a file. The user enters the string he/she is searching...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.