-
Need help with Strings
I am trying to write a program where 2 stings are input. The program should check whether second string is part of the first string. For example, if the first string is "there" and second is "here", program should report that second string is part of first. I am having difficulty in figuring out how to do this. Can any one help. I will really appreciate it a lot. This is what I have:
#include <iostream.h>
#include <conio.h>
#include <string.h>
#include <stdio.h>
int find(char[], char[]);
void main()
{
clrscr();
int status;
char firstString[20];
char secondString[20];
cout << "Enter first word: ";
cin >> firstString;
cout << "Enter second word: ";
cin >> secondString;
status = find (firstString, secondString);
if (status == 1)
cout << "First string includes second string.";
else
cout << "First string does not include second string.";
getch();
}
int find (char first[], char second[])
{
int lengthOne = 0, lengthTwo = 0;
int i = 0, flag = 1;
while (first[i] != '\0') {
lengthOne++;
i++;
}
int j =0;
while (second[j] != '\0') {
lengthTwo++;
j++;
}
for (int x = 0; x < lengthOne; x++) {
for (int y = x; y < lengthTwo; y++)
{
if (second[y] != first [y])
{ flag = 0;
break;
}
}
}
if (flag == 1)
return 1;
return 0;
}
-
Well, since this is the C++ forum you could use the C++ string objects and the built in find member function to do this:
Code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1, s2;
cout << "Enter first word: ";
cin >> s1;
cout << "Enter second word: ";
cin >> s2;
if( s1.find(s2) != string::npos )
cout << "First string includes second string.";
else
cout << "First string does not include second string.";
cin.get();
cin.get();
return 0;
}
-
Though it is better to use string objects I think it is likely that this person is learning how to manipulate character arrays for a school assignment.
You don't need these,
Code:
while (first[i] != '\0') {
lengthOne++;
i++;
}
int j =0;
while (second[j] != '\0') {
lengthTwo++;
j++;
}
Look up strlen().
And,
Code:
if (second[y] != first [y])
{ flag = 0;
break;
}
just compares the two strings.
You need step through the first string and at each element, compare that element and the (X - 1) amount of letters following that element with the letters of the second string, where X is the length of the second string.
You can use strcmp() for that.
So in your example the search would compare,
'ther' and 'here' the first time and 'here' and 'here' the second time.
Hope that helps.
-
thanks a lot, acutally I do know several string functions, including strlen(), etc. But the person I am trying to help in his assignment is only allowed to use the function that he has been taght so far in class. I would like to compare each letter of the second string with lettes of the first string starting with first letter. Can't figure out how to do that. I hope I made myself clear. Something is missing in what I wrote which I can't figure out. Thanks a lot.
arooj
-
Well this is very ugly but I have tried to keep your code as close to how it was as possible. Change your nested loop to,
Code:
for (int x = 0; x < lengthOne; x++) {
flag = 1;
for (int y = 0; y < lengthTwo; y++)
{
if (second[y] != first [x + y])
{
flag = 0;
break;
}
}
if (flag == 1)
break;
}
Soz about the formatting. I did it in Dev C++ which is awful at formatting.
-
Greetings,
But i bet you can make your own functions.
Anyway, here's an example on how to find a string inside another:
Code:
#include <iostream> // This is the standard header. 'iostream.h' is deprecated
// and should no longer be used
// using namespace std; // uncomment this line if you don't want to type std::
// before every 'cout', 'cin', 'endl', etc.
int string_length(const char* string);
int string_find(const char* source, const char* what);
int main()
{
char firstString[100], secondString[100];
int found = 0;
std::cout << "Enter first string: ";
std::cin.getline(firstString, 100); // I'm using getline because this way I can input more than
// one word.
std::cout << "Enter second string: ";
std::cin.getline(secondString, 100);
found = string_find(firstString, secondString);
if (found != -1)
std::cout << "Found at position " << found << std::endl;
else
std::cout << "Not found." << std::endl;
return 0;
}
int string_length(const char* string)
{
int length = 0;
while (string[length] != 0)
++length;
return length;
}
int string_find(const char* source, const char* what)
{
int len_source = string_length(source);
int len_what = string_length(what);
for (int i=0;i<len_source;++i) {
if (source[i] == what[0]) { // We have a match for the first char. Let's check the rest...
for (int j=0;j<len_what,source[i+j] == what[j];++j);
if (j >= len_what) // '>=' because if 'what is at the end of 'source' j=len_what+1
return i; // return the position where 'what' was found
}
}
return -1; // -1 -> not found
}
Sample output:
Code:
Enter first string: The rain in Spain stays mainly in the plane.
Enter second string: Spain
Found at position 12
Enter first string: The rain in Spain stays mainly in the plane.
Enter second string: plane
Found at position 38
Enter first string: The rain in Spain stays mainly in the plane.
Enter second string: The
Found at position 0
Enter first string: The rain in Spain stays mainly in the plane.
Enter second string: whatever
Not found.
-
augur, use && rather than , in your case it doesn't matter, but it might be confusing.
The first thing to note is that you really don't need the length. If one string ends before the other, then one string will have a zero at the same position as the other has non-zero. You only need to guard against the special case of both strings being of equal length. To do this you simply have to check one of the strings against zero.
The other trick is to write this in terms of a slightly less effecient, but easy to write and understand, function, "prefix_match"
Code:
inline
bool prefix_match(char *str, char *pat) {
while(*pat && *str==*pat) {++str;++pat;}
return *pat == '\0';
}
We can now write substring_match by observing that a string s has a substring_match iff s+n has a prefix_match.
Code:
bool substring_match(char *str, char *pat) {
while(*str && !prefix_match(str,pat)) ++str;
return *str != '\0';
}
We can speed up the code significantly by first searching the string for pat[0] and only calling prefix_match where the first characters match. There are even fancyer ways to do this that involve comparing each character in the string only once, but they are a bit beyond the scope here.