I am trying to make a bool function that will allow an input of a string and the input of a substring to be searched in that string's input. The bool function should search recursively for a match, then return true if there is a match inside of the string. For example: 'word' is entered as the string, then 'or' is the substring I am looking for inside the string. The function should then return true since 'or' is inside 'word'. When I run the code, on the command line it will say, "process is terminated due to StackOverFlowException" I am confused as to what this error means and how it relates to my code.
#include <iostream>
#include <string>
using namespace std;
bool find(string s, string t)
{
if(s.length() <= 1){
return false;
}
int t_len = t.length() - 1;
string se = s.substr(0, t_len);
if(se == t){
return true;
}
else
s.erase(0,0);
return find(s, t);
}
int main()
{
string s;
string t;
cout << "Enter string s: " << endl;
cin >> s;
cout << "Enter string t: " << endl;
cin >> t;
bool is_found = find(s, t);
if(is_found = true)
{
cout << "Found: " << t << " in " << s << endl;
}
system("pause");
return 0;
}
Your call to erase is not deleting any characters. The definition of erase is:
erase( size_type index = 0, size_type count = npos );
So you want to erase 1 character, not 0 characters.
Additionally, your test at the end should read:
if(is_found == true)
as otherwise, you're trying to assign is_found the value true and test that value (which will always be true in that case.
Additionally, you have:
string se = s.substr(0, t_len);
where t_len is incorrect (off by one), so the string comparison will not work.
Fundamentally, it looks like you've not understood the definitions of erase or substr, which would be essential to getting this to work properly.
Related
My goal is to make a program that inputs a phone number and outputs it in a standard format. It skips over any non-number characters, will output if there are not enough digits, and will also skip over any digits after the first ten digits. My raptor worked without a hitch, but it's been difficult to translate it to C++.
I am using Microsoft Visual Studio.
The problem is it is not running. If I put in anything more then one number in, I receive a fail error.
I am having some difficulty running this code.
Any and all help and advice would be greatly appreciated.
#include <iostream>
#include <string>
using namespace std;
void format(char outArray[], string inNumber)
{
outArray[0] = '(';
outArray[4] = ')';
outArray[5] = ' ';
outArray[9] = '-';
outArray[1] = inNumber[0];
outArray[2] = inNumber[1];
outArray[3] = inNumber[2];
outArray[6] = inNumber[3];
outArray[7] = inNumber[4];
outArray[8] = inNumber[5];
outArray[10] = inNumber[6];
outArray[11] = inNumber[7];
outArray[12] = inNumber[8];
outArray[13] = inNumber[9];
}
int main()
{
string phone, inNumber;
cout << "Please enter a phone number: ";
cin >> phone;
int index = 0;
int num = 0;
char outArray[14];
for (index; phone[index] >= '0' && phone[index] <= '9'; index++)
{
inNumber[num] = phone[index];
num++;
}
if (inNumber.size() > 10)
{
format(outArray, inNumber);
cout << "The properly formatted number is: ";
cout << outArray;
}
else {
cout << "Input must contain at least 10 digits." << endl;
}
system("pause");
return 0;
}
A few things to note:
Use std::string instead array of char array.
You do not need to check charters using a for loop unless you are not sure about the input(phone). However, if that's the case, use std::getline() to get the input and parse as follows using a range-based for loop.
You can use std::isdigit to check the character is a digit.
My goal is to make a program that inputs a phone number and outputs it
in a standard format. It skips over any non-number characters, will
output if there are not enough digits, and will also skip over any
digits after the first ten digits.
That means the number should have a minimum length of 10. Then the
if statement should be if (inNumber.size() >= 10)
Need a pass by ref call in the function format(), since you want to change the content of outArray. Additionally, inNumber could be a
const ref, since we do not change this string.
Updated code: (See a sample code online)
#include <iostream>
#include <string>
#include <cstddef> // std::isdigit, std::size_t
void format(std::string& outArray, const std::string& inNumber) /* noexcept */
{
for (std::size_t index = 0; index < 10; ++index)
{
if (index == 0) outArray += '(';
else if (index == 3) outArray += ") ";
else if (index == 6) outArray += '-';
outArray += inNumber[index];
}
}
int main()
{
std::string phone;
std::cout << "Please enter a phone number: ";
std::getline(std::cin, phone);
std::string inNumber;
for (char letter : phone)
if (std::isdigit(static_cast<unsigned char>(letter))) // check the letter == digits
inNumber += letter;
if (inNumber.size() >= 10)
{
std::string outArray;
format(outArray, inNumber);
std::cout << "The properly formatted number is: ";
std::cout << outArray;
}
else {
std::cout << "Input must contain at least 10 digits." << std::endl;
}
return 0;
}
inNumber[num] = phone[index]; //undefined behavior.
You cannot subscript inNumber now, since its capacity is 0, thus it can not store or access any element here.
You may need to use string's constructor whose parameter has a size_t type or string::reserve or string::resize.
And I'm happy to see cppreference get more complete now, learn to use it: http://en.cppreference.com/w/cpp/string/basic_string
BTW, this function won't do anything you want to:
void format(char outArray[], string inNumber)
maybe you'd like to have an signature like this?
void format(char outArray[], string& inNumber)
I'm a beginner in coding with C++. I'm trying to make a program that completes a specific set of tasks:
opens a data file,
takes each line of the file,
processes each line by removing all whitespace and punctuation,
converts the string into all lowercase,
uses a recursive method to test if the string is a palindrome,
finds a position within the string where characters can be added to make it a palindrome if it isn't already,
then adds the characters needed to make it a palindrome in the position specified in (6).
I'm only allowed to use 4 user-defined functions with specific parameters. So far I've got about 80% of the program to work, but there's an error when it detects a non-palindrome. I'm hoping someone can find out why. Here's my code:
// Read file data, check for palindromes, and process strings to palindromes.
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
using namespace std;
string process(string);
bool is_palindrome(string);
int palindrome_fix_location(string);
string palindrome_addition(string, int);
int main()
{
ifstream inFile;
inFile.open("data");
string preString;
int palinLoc = 0;
while(getline(inFile, preString))
{
cout << "\nOriginal line: " << preString << endl;
cout << "Processed line: " << process(preString) << endl;
if (is_palindrome(preString) == true)
cout << "Line is palindrome." << endl;
else
cout << "Line is NOT a palindrome." << endl;
palindrome_fix_location(preString);
palindrome_addition(preString, palinLoc);
}
inFile.close();
return 0;
}
// Return a string that is lowercase with no punctuation or spacing.
string process(string preString)
{
string procString;
for (size_t i = 0; i < preString.length(); i++)
{
if (isalnum(preString[i]))
procString += tolower(preString[i]);
}
return procString;
}
// Uses a recursive method to determine if the processed string is a palindrome.
bool is_palindrome(string procString)
{
string temp = process(procString);
int length = temp.length();
string firstChar = temp.substr(0, 1);
string lastChar = temp.substr((length - 1), 1);
if (firstChar == lastChar)
{
temp = temp.substr((0 + 1), (length - 2));
if (temp.length() <= 1) // Base case.
return true;
return is_palindrome(temp); // Recursion.
}
else
return false;
}
// Return a location where text can be added to the non-palindrome to make it a palindrome.
int palindrome_fix_location(string procString)
{
string temp = process(procString);
if (is_palindrome(temp) == false)
{
int palinLoc;
int firstChar = 0, lastChar = temp.length() - 1;
while (firstChar < lastChar)
{
if (temp[firstChar] != temp[lastChar])
{
palinLoc = firstChar;
cout << "Characters to insert at location "
<< palinLoc << " are ";
return palinLoc;
}
}
}
return 0;
}
// Return the text that needs to be added at the "palinLoc" location.
string palindrome_addition(string procString, int palinLoc)
{
string temp = process(procString);
string addedChars;
string finalString;
if (is_palindrome(temp) == false)
{
int firstChar = 0, lastChar = temp.length() - 1;
while (firstChar < lastChar)
{
do {
addedChars += temp[lastChar];
} while (temp[firstChar] != temp[lastChar]);
firstChar++;
lastChar--;
}
finalString = temp.insert(palinLoc, addedChars);
cout << addedChars << endl;
cout << "Final word: " << finalString << endl;
return finalString;
}
else
return finalString;
}
And here's the output I get:
Original line: lappal
Processed line: lappal
Line is palindrome.
-
Original line: lapal
Processed line: lapal
Line is palindrome.
-
Original line: A man, a plan, a canal, Panama!
Processed line: amanaplanacanalpanama
Line is palindrome.
-
Original line: lap
Processed line: lap
Line is NOT a palindrome.
Right there when it says "Line is NOT a palindrome," it's supposed to follow up with something that looks like this:
Characters to insert at location 0 are pa
Final line: palap
It just stops at "Line is NOT a palindrome." Can anyone see where I went wrong with this?
Any help would be greatly appreciated.
your loop here (in palindrome addition) is bugged
do {
addedChars += temp[lastChar];
} while (temp[firstChar] != temp[lastChar]);
it never ends
so you should move either lastchar or firstchar change inside, like this for example
while (firstChar < lastChar)
{
do {
addedChars += temp[lastChar];
lastChar--;
} while (temp[firstChar] != temp[lastChar])
firstChar++;
}
some run here
Original line: lap
Processed line: lap
Line is NOT a palindrome.
start palindrom fix
Characters to insert at location 0 are
start palidrome addition
pa
Final word: palap
Original line: lapin
Processed line: lapin
Line is NOT a palindrome.
start palindrom fix
Characters to insert at location 0 are
start palidrome addition
nipa
Final word: nipalapin
Original line: lapal
Processed line: lapal
Line is palindrome.
I've sadly read every post pertaining to this topic and can't seem to solve my issue. It's driving me mad.
For some reason on my second or third iteration, if (beg != end) won't return false. It returns false properly if I input, for instance, "bool", but not "blob."
I printed beg and end to make sure things are flowing properly, but still can't find where things are going wrong.
Thank you!!!
#include <iostream>
#include <string>
using namespace std;
bool palindrome_check (string str)
{
string return_str;
int length = str.length()-1;
string beg = str.substr(0, 1);
string end = str.substr(length, 1);
if (beg != end)
{
// cout << beg << " " << end << endl;
return false;
}
else if ((str.length() > 2) && (str.length() != 0))
{
string new_str = str.substr(1, length - 1);
// cout << new_str << endl;
palindrome_check(new_str);
}
return true;
}
int main ()
{
string input;
cout << "Enter a string: ";
cin >> input;
bool is_palindrome = palindrome_check (input);
cout << is_palindrome << endl;
}
You should have used the return values of recursive calls:
string new_str = str.substr(1, length - 1);
return palindrome_check(new_str);
}
return true;
And you should have checked the length of the input string before you extract the first and the last character from it.
If you fix the two mistakes, it should be alright then.
For my assignment I have to have two functions (a main function and a recursive helper function) and the purpose is to search for a string within a string then provide the index that string starts at. Example:
String: Hi I am a horse
String to search for: horse
Returns: 10
I have written a program that will do this, but the only problem is in my recursiveHelper function I check the next index by
return recursiveHelper(s.substr(1), t, ++count);
which my teacher informs me that string s should not be changed when calling the helper function. Can someone tell me why and also provide me a way to do it as I have been looking all weekend to not avail. Thanks!
Full program:
#include <iostream>
#include <string>
using namespace std;
// recursiveHelper function
// purpose: locate the first instance of the string t within the string s
// Parameters: string, string, int
// Returns: int
int recursiveHelper(string s, string t, int count)
{
// Length variables
int inputOneLength = s.length();
int inputTwoLength = t.length();
// Figure out the base case. Same format as lab10 really
if (inputOneLength < inputTwoLength)
{
return -1;
}
else
{
// Check the first index -- compare the strings character by character
if (s.substr(0, inputTwoLength) == t)
{
return count;
}
else
{
// Check the next index
return recursiveHelper(s.substr(1), t, ++count);
}
}
}//end of recursiveHelper
// index_of function
// purpose: locate the first instance of the string t within the string s
// Parameters: string, string
// Returns: int
int index_of(string s, string t)
{
// Initialize the count
int count = 0;
// Send to the helper
count = recursiveHelper(s, t, count);
return count;
}//end of index_of
int main()
{
// Variables
string inputOne = "";
string inputTwo = "";
// Prompt user input
cout << "This program will find the occurence of one string inside another." << endl;
cout << "\nEnter the string to be searched: ";
getline(cin, inputOne);
cout << "Now enter the string you want to search for: ";
getline(cin, inputTwo);
// Pass to index_of function
int index = index_of(inputOne, inputTwo);
// Output results
if (index != -1)
{
cout << "The index of substring is = " << index << endl;
}
else
{
cout << "Can't find this string." << endl;
}
system("PAUSE");
return 0;
}//end of main
Your teacher is wrong.
s is never changed!
here is the definition of string::substr()
string substr (size_t pos = 0, size_t len = npos) const;
the const keyword means the method doesn't change the object.
you always get a new string from the call tostring::substr()
I'm currently learning about vectors and trying to make a palindrome program using them. This is a simple program and so far, I'm trying to make it identify "I am what am I." as a palindrome properly. This is my program so far:
#include <vector>
#include <string>
#include <iostream>
using namespace std;
vector <string> sentVec;
void getSent(string sent);
void readBackwards(string sent);
int main()
{
string sent;
getSent(sent);
readBackwards(sent);
return 0;
}
void getSent(string sent)
{
cout << "Enter your sentence:" << endl;
getline (cin,sent);
string currentWord, currentLetter;
for (int i = 0; i < sent.length(); i++)
{
currentLetter = sent[i];
if (currentLetter == " ") // inserts word
{
currentWord += sent[i];
sentVec.push_back(currentWord);
currentWord = "";
}
else if (currentLetter == ".") // inserts period
{
sentVec.push_back(currentWord);
currentWord = sent[i];
sentVec.push_back(currentWord);
}
else
{
currentWord += sent[i];
}
}
}
void readBackwards(string sent)
{
string sentForwards, sentBackwards;
// create sentence forwards and backwards without the period.
for (int i = 0; i < sentVec.size() - 1; i++)
{
sentForwards += sentVec[i];
}
for (int j = sentVec.size() - 2; j >= 0; j--)
{
sentBackwards += sentVec[j];
if (j == sentVec.size() - 2)
{
sentBackwards += " ";
}
}
cout << "Sentence forwards is: " << sentForwards << endl;
cout << "Sentence backwards is: " << sentBackwards << endl;
if (sentForwards == sentBackwards)
{
cout << "This sentence reads the same backwards as forwards." << endl;
}
else
{
cout << "This sentence does not read the same backwards as forwards." << endl;
}
}
When I run this program, it prints:
Enter your sentence:
I am what am I.
Sentence forwards is: I am what am I
Sentence backwards is: I am what am I
This sentence does not read the same backwards as forwards.
Why does this not trigger the if loop when comparing the two sentences?
Because sentBackwards isn't the same as sentForwards, because sentBackwards has a trailing whitespace at the end, and thus they aren't the same.
I am unsure how your program detects palindromes, but here is a simple iterative method:
#include <string>
bool isPalindrome(std::string in) {
for (int i = 0; i < in.size() / 2; i++) {
if (in[i] != in[in.size() - 1 - i]) {
return false;
}
}
return true;
}
It returns true if the string passed as an argument is a palindrome
You should not only learn about vector, but also the STL algorithm functions such as std::reverse.
As the other answer given pointed out, one vector has a trailing whitespace. You could have avoided all of that by simply taking the original vector, copying it to another vector, and calling std::reverse. There is no need to write a loop:
void readBackwards()
{
// copy the vector
std::vector<std::string> sentBackwards = sentVec;
// reverse it
std::reverse(sentBackwards.begin(), sentBackwards.end());
// see if they're equal
if (sentVec == sentBackwards)
cout << "This sentence reads the same backwards as forwards." << endl;
else
cout << "This sentence does not read the same backwards as forwards." << endl;
}
This works, since std::vector has an overloaded operator == that compares the items in each of the two vectors and returns true if all items are the same.
In addition to this, reading into a vector can be accomplished much more easily than what you attempted.
#include <sstream>
#include <algorithm>
//...
void getSent(string sent)
{
// remove the periods(s)
auto iter = std::remove_if(sent.begin(), sent.end(), [] (char ch) { return ch == '.';});
sent.erase(iter, sent.end());
// copy the data to a vector
std::istringstream iss(sent);
string currentword;
while ( iss >> currentword)
sentVec.push_back(currentword);
}
Note that we use the std::istringstream to serve as the space delimited parser, alleviating the need to write a loop looking for the space. Also, the std::remove_if algorithm is used to remove any period characters from the string before we start to store the individual strings into a vector.
So basically, the only loop in this whole setup is the while to read from the stream into the vector. Everything else is accomplished by using the algorithm functions, and taking advantage of the various member functions of std::vector (like the overloaded ==)