How can I get tis to work by passing a string to a Boolean function? I need to have the user input a series of strings, and after each entry, the program should give feedback depending upon whether or not the string fit the given criteria. The string should contain the substring of "1101", without any letters. Thanks for all your help
#include <iostream>
#include <cstring> // for strstr
#include <string>
#include <cctype>
using namespace std;
bool stringCompare(char*y);
string str2;
int main ()
{
string str1, str2;
str1= "1101";
do
{
cout << "Please enter your string: " << endl;
cin >> str2;
while((stringCompare(str2)) == true)
{
if(strstr(str2.c_str(),str1.c_str())) // Primary string search function
{
cout << "ACCEPTED " << endl;
}
else
cout << "NOT ACCEPTED " << endl;
}
} while (2 > 1);
return 0;
}
bool stringCompare(char*y)
{
for(int a = 0; a < strlen(str2); a++)
{
if (!isdigit(str2[a]))
return false;
}
return true;
}
stringCompare takes a parameter of type char*, but you're trying to pass a std::string. That won't work.
You can either use the c_str method of std::string, to get a const char* pointing to the std::string's internal char array. This means that you'll have to chance the parameter to const char*.
Or, much better, you can replace stringCompare to take a reference to a std::string:
bool stringCompare(string& y)
and change strlen(str2) to str2.length(). (Or even better, replace the whole loop to simply:
for(char& ch : str2) // range-based for-loop loops over the entire str2
{
if (!isdigit(ch))
return false;
}
)
Also, you don't need to compare the return value == true. Just do:
while(stringCompare(str2))
Related
I need to make a program which converts all letters to uppercase.
But first I need to get an input from the user. And I need to check if there are characters that are not space or alphabet.
This is what I tried.
#include <iostream>
#include <cctype>
using namespace std;
int main()
{
string s;
cout << "Enter a string: ";
while (getline(cin, s)){
for (int i = 0; i<s.length(); i++){
if ((isspace(s[i]) || isalpha(s[i]))){
for (int i = 0; i < s.length(); i++){
s[i] = toupper(s[i]);
}
cout << s << endl;
return 1;
}
cout << "Invalid string. Please input only alphabets or space character. " << endl << "Enter a string: ";
}
}
//if the input value is valid convert and print
return 0;}
This program successfully make error messages to pure numbers and pure question marks. But the problem is if there are invalid characters and valid characters mixed in the input, it cannot distinguish it.
For example, if input is "Hi?", the program thinks its a valid input. But with questions marks, the string should be invalid.
I think the for statement is the problem. How can I solve this?
I've made a few changes to deal with the break out conditions in your loops without changing the structure of your program too much.
Here's one example how you could get it to work. Comments in the code.
#include <cctype>
#include <iostream>
#include <string>
int main() {
std::string s;
while(std::cout << "Enter a string: " && std::getline(std::cin, s)) {
bool valid = true; // will stay true unless at least one char is invalid
for(char& ch : s) { // use a range-based for loop
// ch is now a reference to the char in the string
// convert to unsigned char - these functions are not safe
// otherwise:
if(std::isspace(static_cast<unsigned char>(ch)) ||
std::isalpha(static_cast<unsigned char>(ch)))
{
ch = std::toupper(static_cast<unsigned char>(ch));
continue; // continue to check the next character
}
std::cout << "Invalid character ('" << ch << "') in string.\n"
"Please input only alphabets or space character.\n";
valid = false; // to let the user enter a new string
break; // no need to check more characters, the string is invalid
}
if(valid) break; // break out only if all characters are valid
}
if(std::cin)
std::cout << "The valid string is now " << s << '\n';
}
A similar program could use algorithms from <algorithm> to do the check and the transformation of the string to uppercase.
Example:
#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>
int main() {
std::string s;
// the manual loop replaced by a simple algorithm that checks if any
// character in the string is invalid by using a lambda, here called
// "is_invalid":
auto is_invalid = [](unsigned char ch) {
return !(std::isspace(ch) || std::isalpha(ch));
};
while(std::cout << "Enter a string: " &&
std::getline(std::cin, s) &&
std::any_of(s.begin(), s.end(), is_invalid))
{
std::cout << "Invalid character in string.\n"
"Please input only alphabets or space character.\n";
}
if(std::cin) {
// transform the valid string to uppercase using another lambda.
// the lambda is here only to make the chars into unsigned chars
// to make the use of std::toupper safe
auto to_upper = [](unsigned char ch) { return std::toupper(ch); };
std::transform(s.begin(), s.end(), s.begin(), to_upper);
std::cout << "The valid string is now " << s << '\n';
}
}
I have prototype - int replace_char(string &, char);
I can't use library from string and ctype.h, I should write my own function.
So the task is to find in the text caharacter, which should I should replace with "*" .
example: In This is my text .
replace all t to * . Result will be - *his is my *ex*.
#include <iostream>
using namespace std;
int replace_char(string &, char);
int main ()
{
cout << ""Please insert text:"
cin >> str;
}
int replace_char(string str, char c1)
{
for (int i = 0 ; i < str.length(); i++)
{
if(str[i]==c1)
str[i]='*';
}
return str;
}
There were several errors in the code:
The function signature mismatches, the prototype is defined as std::string& but in the function definition, std::string only was used.
The program never converted the capital letter T or anything which is capital in order to convert them before comparing each letter with a single char.
The function is never used in the code.
cin >> str won't take longer texts followed by next whitespace character.
The function wants to return an integer, but actually returned type was a std::string, which is totally a misunderstanding.
The code redefined:
#include <iostream>
// taking a reference of std::string and a char
int replaceText(std::string&, char);
int main(void) {
std::string s;
int rep;
std::cout << "Enter a string: ";
std::getline(std::cin, s); // getline() to accept whitespaces
// since we're using a reference, the original variable is manipulated
int rep = replaceText(s, 't');
std::cout << "Output: " << s << std::endl;
std::cout << "Replaced number of chars: " << rep << std::endl;
return 0;
}
int replaceText(std::string& str, char c) {
size_t len = str.length();
static int count;
// changing each letter into lowercase without using any built-in functions
for (size_t i = 0; i < len; i++)
if (str[i] >= 'A' && str[i] <= 'Z')
str[i] = str[i] + 32;
// replacing the character, the main work
for (size_t i = 0; i < len; i++)
if (str[i] == c) {
str[i] = '*';
count++; // count a static variable
}
return count; // returning the overall counts
}
The program firstly takes an input from the user of type std::string and uses reference to the variable str. Now the program enters to the function code.
In the beginning, the function converts each letter to lowercase without using any library or a built-in function. Afterwards, it tries to compare each letter of the string carefully and as soon the given character matches a value containing in the string passed to the function, it replaces and counts a static variable which keeps the value save for the entire program life.
Thereafter, it simply displays the manipulated string.
It outputs something like:
Enter a string: This is a text
Output: *his is a *ex*
Replaced chars: 3
You seem to have a good start.
You need to declare str before reading input into it. Try string str;
Then you need to use your function in main. Either store its output into another string like string replaced = replace_char(str, 't');
Or put it into the output directly like cout << replace_char(str, 't') << endl;
Probably this is what you need
#include <iostream>
using namespace std;
int replace_char(string &, char);
int main ()
{
string str;
cout << "Please insert text:"
std::getline(cin, str);
int rlen = replace_text(str, 't')
cout << str << endl;
cout << "Number of replaced : " << rlen << endl;
return 0;
}
int replace_char(string str, char c1)
{
int rlen = 0;
for (int i = 0 ; i < str.length(); i++)
{
if(str[i]==c1) {
str[i]='*';
rlen++;
}
}
return rlen;
}
Given the prototype of the function, I'm guessing you need to return the number of chars replaced. This implementation should work:
#include <string>
#include <iostream>
using namespace std;
int replace_char(string &, char);
int main ()
{
cout << "Please insert text:";
string str;
getline(cin, str);
int nCharsReplaced = replace_char(str, 't');
}
int replace_char(string& str, char c1)
{
int count = 0;
for (int i = 0 ; i < str.length(); i++)
{
if(str[i]==c1)
{
str[i]='*';
count++;
}
}
return count;
}
Keep in mind there's no need to return the string, as you're passing it by reference, so the argument itself is modified.
Also, if you want the example you provided to work the replace_char functions cannot be case sensitive, since you replaced the capital 'T' with '*' too. In order to achieve that, you could implement a function that turns every char to lowercase (ideally, you would use tolower from ctype):
char to_lower_case(char c)
{
return c - ('Z' - 'z');
}
And replace the if condition with:
if (to_lower_case(str[i]) == c1)
If you don't understand how this work, take a look at how ASCII works.
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
void LowerCharacters(string& text);
void OutPutEachLetter(string text, int* ptr);
void comparePointers();
int main() {
string text1, text2; bool isAnagrams = true;
int *ptr1=NULL, *ptr2=NULL;
cout<<"Please enter first string ";
getline(cin,text1);
cout<<"Please enter second string ";
getline(cin,text2);
LowerCharacters(text1);
LowerCharacters(text2);
OutPutEachLetter(text1, ptr1);
OutPutEachLetter(text2, ptr2);
for(int i =0; i<26;i++) {
if (ptr1[i] != ptr2[i]) {
isAnagrams = false;
}
}
if(isAnagrams)
cout<<"These two strings are anagrams";
else
cout<<"These two strings are not anagrams";
delete []ptr1; delete []ptr2;
ptr1=NULL; ptr2=NULL;
}
void LowerCharacters(string& text) {
for (int i = 0; i < text.length(); i++) {
text[i]=tolower(text[i]);
}
}
void OutPutEachLetter(string text, int* ptr){
ptr = new int[26];
*ptr = {0};
for(int i =0;i<text.length()-1;i++)
{
ptr[text[i]-'a']++;
}
for(int j=0;j<26;j++){
if(ptr[j]!=0){
cout<<ptr[j]<<"\t"<<char(j+'a')<<endl;
}
}
}
Above was my code. I thought it would have worked but it did not. it printed the ptr1 successfully but never printed the ptr2. I want to know why... Any help will be appreciated!
I am kind of new to pointer stuff, I just wanted to try my best to use the pointer in my code so that I can practice more. I know that I can totally just create two static arrays in the main part and then write the array in my function OutputEachLetter as an argument and use the pass as a reference like int &arr. However, I really want to know why is my current code wrong and why am I not allowed to use this kind of code.
You could just do a little effort by adding algorithm library plus you're using C++, take some benefits of it. Just use the transform() for conversion of strings into lower case, and sort them then see if they're equal or not.
Everything could be done in a simplified way.
Consider the written program:
#include <iostream>
#include <algorithm>
int main(void) {
std::string str1, str2;
std::cout << "Enter the first string: ";
std::getline(std::cin, str1);
std::cout << "Enter the second string: ";
std::getline(std::cin, str2);
/* --- this --- */
transform(str1.begin(), str1.end(), str1.begin(), ::tolower);
transform(str2.begin(), str2.end(), str2.begin(), ::tolower);
std::sort(str1.begin(), str1.end());
std::sort(str2.begin(), str2.end());
if (str1 == str2)
std::cout << "Both strings are anagrams";
else
std::cout << "No anagrams";
std::cout << std::endl;
return 0;
}
Write a function that accepts a c-string and a character as parameters. Returns the number of times the character appears in the string.
I also have to do this in my program:
Convert strings A and B to all lower case. For each letter in string A, call function on A and B.
This is the code I have so far:
#include <iostream>
#include <cstring>
#include <cctype>
using namespace std;
char tolower(char c) {
return c;
}
int countChars(const char* string, char ch)
{
int count = 0;
int i;
int length = strlen(string);
for (i = 0; i < length; i++)
{
if (string[i] == ch)
{
count++;
}
}
return count;
}
int main() {
char stringA[50];
char stringB[50];
cout << "Please enter first string: ";
cin.getline(stringA, 50);
cout << "Please enter second string: ";
cin.getline(stringB, 50);
cout << "String 1: " << stringA << endl;
cout << "String 2: " << stringB << endl;
if (strcmp(stringA, stringB) == 0) {
cout << "These strings are anagrams" << endl;
}
else {
cout << "These strings are not anagrams" << endl;
}
}
If you want to do so in a simple and readable way, consider the following code:
#include <string>
#include <iostream>
#include <algorithm>
bool is_anagram(std::string s1, std::string s2)
{
std::sort(s1.begin(), s1.end());
std::sort(s2.begin(), s2.end());
return s1 == s2;
}
int main(void)
{
std::string s1, s2;
std::cout << "Input first string: ";
getline(std::cin, s1);
std::cout << "Input second string: ";
getline(std::cin, s2);
if (is_anagram(s1, s2))
std::cout << "Strings are anagrams." << std::endl;
else
std::cout << "Strings are NOT anagrams." << std::endl;
return 0;
}
The function is_anagram() returns true when the sorted strings (used algorithm library for it) are same.
Note: The strings are case-sensitive. Hello and hello are different.
Hope it helps you. :D
Just sort the both the strings and then compare it.
sort(stringA, stringA+strlen(stringA))
sort(stringB, stringB+strlen(stringB))
just before the if statement.
You were checking if the 2 strings are exactly equal. But anagrams can have different arrangement of letters but must have same letters.
Though you need to check may need to check if the 2 strings are same (if you don't consider a string to be an anagram of itself).
PS- a google search would have instantly provided you ans.
The easiest way to do this is to count the number of each letter. Note you don't need to count every letter just the ones are in the string. To compare them store the results in a map.
#include <iostream>
#include <string>
#include <map>
#include <array>
class AnagramCheck
{
// I am going to be lazy and use map to store the counts.
// But you can do this much smarter and get a better complexity
// by using an array. But that involves more checks
std::map<char, int> data;
public:
explicit AnagramCheck(std::string const& str)
{
for(auto x: str) {
++data[std::tolower(x)]; // If you want to be smart ignore space/punctuation
}
}
bool operator==(AnagramCheck const& rhs) const
{
return data == rhs.data;
}
};
int main()
{
std::string line1;
std::getline(std::cin, line1);
AnagramCheck line1Check(line1);
std::string line2;
std::getline(std::cin, line2);
AnagramCheck line2Check(line2);
if (line1Check == line2Check) {
std::cout << "Anagram\n";
}
}
I am looking to check if two string are permutations of each other. I am using the following code :
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
void sort(char *str)
{
char temp;
for(int i=0;i<strlen(str);i++)
{
if(str[i]>str[i+1])
{
temp=str[i];
str[i]=str[i+1];
str[i+1]=temp;
}
}
}
int main()
{
char string1[10],string2[10];
int val;
cout<<"Enter first string";
gets(string1);
cout<<"Enter second string";
gets(string2);
val = strcmp(sort(string1),sort(string2));
if(val==0)
{
cout<<"Same strings"<<endl;
}
else
{
cout<<"Different Strings"<<endl;
}
return 0;
}
But I am getting a "invalid use of void expression error" at the strcmp line. How do I fix this ?
Thanks
It looks like you want to compare strings after sorting. Assuming your sort function does the right thing, you need to compare the strings after sorting them.
sort(string1);
sort(string2);
val = strcmp(string1, string2);
The reason for the error is that your sort function returns void. So you are effectively passing void arguments to strcmp. And that can't work.
The way to do this in C++ would be to use std::string, and call std::sort.
std::string string1, string2;
std::cout << "Enter first string";
std::cin >> string1;
std::cout << "Enter second string";
std::cin >> string2;
std::sort(string1.begin(), string1.end());
std::sort(string2.begin(), string2.end());
bool val = string1 == string2;
sort returns nothing (void), so its return value cannot serve as parameter to strcmp.
sort(string1);
sort(string2);
val = strcmp(string1, string2);
You can't strcmp the void returns from sort(). You want to sort() first and then strcmp the sorted strings, something like:
sort(string1);
sort(string2);
val = strcmp(string1, string2);